Promise + 事件循环
怎样实现一个promise?
1.promise是一个类,类中需要一个executor执行器,默认会立即执行。(相当于直接在栈中执行,是一个宏任务。而then后面的微任务,当一个宏任务执行完成后就会清空事件队列中的微任务,详解见下文事件循环机制)
2.promise内部会提供两个方法,注意不是原型上面的,这两个方法会传给用户,可以更改promise状态
3.promise有三个状态:
- 等待(PENDING)
- 成功(RESOLVED)返回成功的结果,如果不写结果返回undefined
- 失败(REJECTED)返回失败的原因,如果不写原因返回undefined
4.promise只会从等待变为成功,或者从等待变为失败
5.每个promise实例上都要有一个then方法,分别是成功和失败的回调
promise几个重要知识点
1.then方法返回的必须是一个promise,这样才能保证链式调用。
2.如果then内部的回调函数执行结果依然是一个promise那就把这个promise的结果resolve出去。
3.任何一个promise必须是resolve之后才能走到then方法,从而创建下一个的promise
4.什么时候走成功回调?then中返回一个普通值或者成功的promise
5.什么时候走失败回调?返回一个失败的promise或者抛出异常
JS的事件循环
主线程从“任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制称为Event Loop(事件循环)
。
此机制具体如下:
- 执行一个宏任务(栈中没有就从事件队列中获取)
- 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
- 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
- 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
- 渲染完毕后,JS线程继续接管,开始下一个宏任务
举个例子
console.log('start');
// 宏任务
setTimeout(function() {
console.log('timeout1');
}, 10);
new Promise(resolve => {
// 立即执行宏任务
console.log('promise');
resolve();
setTimeout(() => console.log('timeout2'), 10);
}).then(function() {
// 微任务
console.log('then1')
}).then(function() {
// 微任务
console.log('then2')
})
console.log('end');
输出结果script start, promise, end, then1, then2, timeout1, timeout2
参考文档:https://juejin.cn/post/6844904088963022856
参考文档:https://juejin.cn/post/6844903874587787278