Promise
// Promise至少要记住的:
// 1、Promise是一个异步操作
// 2、Promise的实例方法:then和catch。
// 3、Promise的类方法:all。 当同时执行多个异步操作(并发)需要用到all。then里面函数的调用需要等到所有的异步操作完毕
// 进一步解释:
// 1、既然Promise是一个异步操作,那就把以前学的异步操作的代码放在Promise里。
function fn01(){
let p = new Promise(function(resolve,reject){
// 这里面写以前的异步代码就行。
resolve(实参);
});
return p;
}
// 2、Promise的实例方法:then和catch。
// then方法:第一个参数是resolve;第二个参数是reject;
// catch方法:参数就是reject(then方法的第二个参数);
let p1 = fn01();
p1.then(function(形参:resolve的实参){
})
// 3、Promise的类方法:all。
Promise.all([多个异步操作(promise对象)]).then(function(多个resolve调用的实参数组){
})
一.promise的基本使用
let success = false;
// l、new Promise();
let p = new Promise(function (resolve, reject) {
console.log("promise内部1");
// resolve:异步操作成功后调用函数
// reject:是异步操作失败后调用的函数
setTimeout(function () {
if (success == true) {
resolve();
} else {
reject();
}
}, 1000);
console.log("promise内部2");
})
// 2、使用
// p.then(resolve对应的函数定义,reject对应的函数的定义)
p.then(function () {
console.log("resolve");
}, function () {
console.log("reject");
})
promise查看类
二.Promise解决回调地狱的代码
// Promise表示一个异步操作
function fn1() {
console.log("fn1开始");
let p = new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("fn1的异步操作");
resolve();
}, 1000);
});
console.log("fn1结束");
return p;
}
function fn2() {
console.log("fn2开始");
let p = new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("fn2的异步操作");
resolve();
}, 1000);
});
console.log("fn2结束");
return p;
}
function fn3() {
console.log("fn3开始");
let p = new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("fn3的异步操作");
resolve();
}, 1000);
});
console.log("fn3结束");
return p;
}
function fn4() {
console.log("fn4");
}
// 如果是Promise,那么代码如下:
fn1().then(fn2).then(fn3).then(fn4);
三.Promise catch方法,then方法的参数传递,Promise.all,Promise.race
//============================Promise catch方法================================
// catch 方法的参数就是then方法的第二个参数。也就是reject
let code = 500;
function fn1() {
console.log("fn1开始");
let p1 = new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("fn1的异步操作");
if (code == 200) {
resolve && resolve();
} else {
reject && reject();
}
}, 1000);
});
console.log("fn1结束");
return p1;
}
function success() {
console.log("success");
}
function fail() {
console.log("fail");
}
fn1().then(success).catch(fail)
//============================Promise then方法的参数传递================================
function fn1() {
let p1 = new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("fn1的异步操作");
resolve && resolve();
}, 1000);
});
return p1;
}
// 1、上一个then方法(里的函数)的返回值 是下一个then方法(里的函数)的参数
fn1()
.then(function () {
console.log("fn1 里的异步操作成功");
return 1;
})
.then(function (num) {//num:是1。也就是上一个函数的返回值。
console.log("num", 1);
})
//============================Promise.all=============================================
// Promise.all:
// 同时执行多个异步操作(并发),
// then方法的参数(回调函数)的调用时机:所有的异步操作都完毕后调用。
function fn01() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("fn01的异步操作完毕");
resolve("fn01成功的结果");
}, 2000)
})
}
// fn01().then(function(str){
// })
function fn02() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("fn02的异步操作完毕");
resolve("fn02成功的结果");
}, 1000)
})
}
// fn02().then(function(str){ })
Promise.all([fn01(),fn02()]).then(function(arr){//arr 里面存储中fn01和fn02里面的resolve的结果。是个数组
console.log("arr",arr);
})
//============================Promise.race=============================================
// Promise.race:
// 同时执行多个异步操作(并发),
// then方法的参数(回调函数)的调用时机: 最快的异步操作完毕后就调用。
function fn01() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("fn01的异步操作完毕");
resolve("fn01成功的结果");
}, 2000)
})
}
function fn02() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("fn02的异步操作完毕");
resolve("fn02成功的结果");
}, 1000)
})
}
Promise.race([fn01(),fn02()]).then(function(str){//str 里面存储中最快的异步操作的resolve的结果。
console.log("str",str);
})
四.asynce和await
// ES7 新增的两个关键字:async和await。这两个关键字彻底解决了回调地狱。
// async:异步。
// 1)、async是可以修饰函数的。
// 2)、async修饰的函数:返回值会变成promise对象。原始函数的返回值,变成了promis对象resolve的实参
// await:等待。await是修饰promise对象的。
// 1)、await只能出现在async修饰的函数里。
// 2)、await修饰Promise后,结果是resolve的实参。
// 3)、await 修饰符,会让其所在行后面的代码处于等待状态。等到await修饰的promise对象里的异步操作完毕后(也就是说resolve调用后)。
// 代码:
// 1、async的代码:
// async function fn01(){
// return "fn01的返回值"
// }
// let str = fn01();
// console.log("str",str);
// str.then(function(result){
// console.log("result",result);
// })
// 2、await:
// async function fn01(){
// let p = await new Promise(function(resolve,reject){
// resolve("resolve")
// });
// console.log("P",p);
// }
// fn01();
// 3、async和await结合起来解决回调地狱。
function fn01(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve("fn01的异步结果");
},1000);
})
}
// function fn02(){
// fn01().then(function(str){
// console.log("str",str);
// })
// }
async function fn02(){
let str = await fn01(); //await 修饰符,会让其所在行后面的代码处于等待状态。等到await修饰的promise对象里的异步操作完毕后(也就是说resolve调用后)。
console.log("str",str);
}
fn02();
五.Promise的两个类方法(resolve和reject)
// Promise.resolve();是 实例方法的语法糖
// Promise.reject();是 实例方法的语法糖
// 一、 Promise.resolve()
// 当:Promise对象里,只有一个resolve的调用。可以使用语法糖的写法(Promise.resolve())。
// 即:如下代码
// new Promise(function(resolve){
// resolve(4);
// }).then(function(num){
// console.log("num",num);
// })
// 可以变为如下代码:
// Promise.resolve(4).then(function(num){
// console.log("num",num);
// })
// 二、Promise.reject();
// 当:Promise对象里,只有一个reject的调用。可以使用语法糖的写法(Promise.reject())。
// 即:如下代码
// new Promise(function(resolve,reject){
// reject(4);
// }).catch(function(n){
// console.log("n",n);
// })
// 可以变为如下代码:
// Promise.reject(4).catch(function(n){
// console.log("n",n);
// });
六.红绿灯案例
function colorShan(num, id, color) {
document.getElementById(id).style.backgroundColor = color;
document.getElementById(id).innerHTML = num;
return new Promise(function (resolve, reject) {
let myTimer = setInterval(function () {
num--;
if (num <= 0) {//良性冗余
num = 0;
clearInterval(myTimer);
myTimer = undefined;
document.getElementById(id).style.backgroundColor = "white";
resolve();
}
document.getElementById(id).innerHTML = num;
}, 500)
})
}
function shanShan() {
colorShan(5, "redLight", "red")
.then(function () {
return colorShan(6, "greenLight", "green");
})
.then(function () {
return colorShan(3, "yellowLight", "yellow");
})
.then(shanShan);
}
shanShan();