一、Promise是什么及相关需求
- Promise是ES6新增的内置类(new Promise)
- Promise是一个“承诺”设计模式,主要目的是用来解决JS异步编程当中“回调地狱”问题(有效的管控异步编程)
- Promise是用来管控异步编程的,new Promise本身不是异步的,执行它的时候会立即把executor函数执行(只不过我们经常在executor中管控一个异步操作)
- resolve / reject:传递给executor函数的参数(参数值都是函数)
- promise的初始状态是pending,初始值是undefined
- resolve([value]):修改promise的状态为fulfilled/resolved的成功状态,并且改变其值为[value]
- reject([reason]):修改promise的状态为rejected,并且改变其值为[reason]
- 一旦状态发生改变,都不能改变为其他状态了
- 一旦executor函数执行报错,状态也会变为失败态,并且改变其值是失败的原因
- promise中的异步指的是resolve/reject执行,原因:
- 执行这两个方法的时候不仅仅是修改状态和值,还要通知then存储的两个回调函数中的一个执行
- 执行两个方法的时候,需要先等待promise已经基于then把方法存储完毕,有方法后才会去执行
new Promise():TypeError: Promise resolver undefined is not a function
new Promise([executor]): executor 是个可执行的函数
【实例】
- [[PromiseStatus]] Promise状态:pending、fulfilled、rejected
- [[PromiseValue]] Promise的值
【原型】
- then
- catch
- finally
【普通对象】
- reject
- resolve
- all
- race
复制代码
- 基于.then注册成功或失败执行的回调函数,它的返回结果是一个新的promise实例
- new Promise([executor])返回的实例的状态和value是根据resolve/reject执行,再或者[executor]函数执行是否报错来决定的
- .then(…)返回的实例的状态和value是根据.then注册的两个方法,不论哪一个方法执行,执行的返回结果和是否报错来决定状态value => 不论哪一个方法执行,只要不报错状态是成功,报错状态则为失败,方法的返回值就是新实例的value值;特殊:如果返回的是一个新的promise实例,则当前实例的状态和value决定了p2的的状态和value
let p1 = new Promise((sesolve, reject) => { resolve('OK') }) let p2 = p1.then(value=>{ console.log('成功执行', value) }, reason=> { console.log('失败执行', reason) }) p2.then(value=>{ console.log('成功执行2', value) }, reason=> { console.log('失败执行2', reason) }) 复制代码
二、then
- 基于then存放两个回调函数:
- 状态为成功调用第一个回调函数执行,形参的值就是[[PromiseValue]]
- 状态为失败调用第二个回调函数执行
let p = new Promise(resolve, reject) {
resolve('OK')
reject('NO')
}
p.then((value)=>{
console.log('成功执行的函数', value)
}, ()=>{
console.log('失败执行的函数', value)
})
复制代码
2.then注入回调方法的时候,我们可以写也可以不写
.then([fnOK], [fnNo])
.then([fnOK])
.then(null, [fnNo])
.then()
如果状态一旦确定,想去执行.then注入的某个方法,但是此方法没有被注册,则向下顺延(找下一个then中注册的对应方法)
Promise.reject(100)
.then(value=>{
console.log('OK', value);
}/*,reason=>{
return Promise.reject(reason);
}*/)
.then(null/*value=>{
return Promise.resolve(value);
}*/, reason=>{
console.log('NO', reason); //NO,100
return Promise resolve(200);
})
.then(null, reason=>{
console.log('NO', reason);
})
.then(value=>{
console.log('OK', value); //OK,200
})
复制代码
三、catch(reason=>{}) === .then(null, reason=>{})
Promise.reject(100).then(value=>{
console.log('OK', value);
}).catch(reason=>{
console.log('NO', reason);
})
复制代码
四、all / race => 返回一个新的Promise实例
all:等待所有Promise实例都是成功,整体返回的实例才是成功(都成功整体才是成功,有一个失败,整体是失败)
race:等待最新有返回结果的Promise实例,此实例的成功和失败决定最后的成功和失败
function fn1() {
return Promise.resolve(1)
}
function fn2() {
return new Promise(resolve, reject) => {
setTimeout(()=>{
resolve(2)
},2000)
}
}
function fn3() {
return new Promise(resolve, reject) => {
setTimeout(()=>{
resolve(3)
},1000)
}
}
//all: 整体返回的实例才是成功
Promise.all([fn1(),fn2(),fn3()]).then(values=>{
//values[Array]:按照顺序存储每一个实例返回的结果
console.log(values);
}).catch(reason=>{
//一旦有失败的,整体都是失败,存储的是当前这个实例失败的原因
console.log('NO', reason);
})
//race: 以最先到的为准
Promise.race([fn1(),fn2(),fn3()]).then(value=>{
console.log('OK',value);
}).catch(reason=>{
console.log('NO', reason);
})
复制代码
四、面试题:设计一个等待函数,等待N时间后执行要做的事情
function delay( callback,interval = 1000){
return new Promise( resolve =>{
let timer = setTimeout(()=>{
clearTimeout(timer);
timer = null;
resolve();
},interval);
});
}
//第一种
delay(1000).then(()=>{
console.log(1);
return delay(2000);
}).then(()=>{
console.log(2);
return delay(3000);
}).then(()=>{
console.log(3);
})
//第二种
(async function(){
await delay(1000);
console.log(1);
await delay(2000);
console.log(2);
await delay(3000);
console.log(3);
})();
复制代码
五、async、await
是ES7中提供的,它是对promise的一个补充(promise语法糖)
用async修饰一个函数,函数返回的结果都会变成一个promise实例
- 状态:大多数都是成功的,如果代码执行报错,返回失败,或者手动返回一个新的promise实例,则按照新实例的状态处理
用await可以把一个异步任务变为类似于同步的效果(本质不是同步,还是异步,而且是异步中的微任务)
function fn2() {
return new Promise(resolve, reject) => {
setTimeout(()=>{
resolve(2)
},2000)
}
}
function fn3() {
return new Promise(resolve, reject) => {
setTimeout(()=>{
resolve(3)
},1000)
}
}
(async function(){
//方法中想用await,必须把方法基于async修饰
/*
1.先把fn2执行,观察fn2返回的是成功还是失败的promise
2.异步性:它会把当前上下文,await下面的代码整体都当做一个异步的微任务,放置在等待的EventQueue中
3.await只是处理promise实例是成功状态的,如果返回状态是成功,则value拿到的是[[PromiseValue]],并且把之前存储的异步任务拿到栈中让主线程把其执行
4.await处理后,立即把函数执行,哪怕函数立即返回成功或者失败的状态,await也没有把其立即处理,而是先等同步的都执行完, 再去执行这些异步的任务
*/
let value = await fn2();
console.log(value)
})();
console.log(1)
复制代码
六、微任务、宏任务练习题
async function async1 (){
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function(){
console.log('setTimeout')
},0)
async1();
new Promise(function(resolve){
console.log('promise1');
resolve();
}).then(function(){
console.log('promise2');
});
console.log('script end');
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)