event loop
从程序的角度来说。event loop是一个程序结构。用于等待和发送消息和事件。程序中有两个线程,一个负责程序本身的运行,为主线程,一个负责主线程和其他线程的通信。
同步任务 、异步任务、宏任务、微任务
-
同步任务:就是我们的单线程顺序执行的代码,
-
异步任务:分为宏任务和微任务
- 微任务:promise.then、process.nextTick(node的api,把当前任务放在执行栈最后执行,执行站完毕之后,先执行nextTick,在到等待队列找)
- 宏任务:promise(他是立即执行的)、定时器、事件绑定,ajax、callback
js的事件循环
// macroQuene 宏任务队列
// microQuene 微任务队列
// stack 调用栈
console.log(1);
// 全局执行代码
// setTimeout 定义是会首先放入stack执行,完毕会清除。
setTimeout(() => {
// 这个callback1是异步任务,会放入宏任务队列 macroQuene[callback1]
console.log(2);
Promise.resolve().then(() => {
// 这个callback4是微任务,会放入宏任务队列 microQuene[callback4]
console.log(3)
});
});
// new Promise 再次放入stack执行,完毕清除
new Promise((resolve, reject) => {
// 这里是实时执行的,也就是全局执行代码的时候就会执行
console.log(4)
resolve(5)
}).then((data) => {
// 这个callback2回调属于微任务,放入microQuene[callback2]
console.log(data);
})
// 放入stack执行,完毕清除
setTimeout(() => {
// 这个callback3 是异步任务。放入macroQuene[callback1,callback3]
console.log(6);
})
// 全局执行代码、
console.log(7);
// 整个代码执行顺序。先执行1,4,7,全局调用结束了,此时microQuene是[callback2],macroQuene[callback1,callback3],从microQuene取出callback1到调用栈执行,
// 得到5,取出宏队列的队头数据,放入调用栈执行,得到2,遇到新的微任务,放入microQuene[callback4],调用栈先调用microQuene,取出callback4,得到3,microQuene没有数据了,
// 执行宏任务队列任务,callback3,得到6 最后的结果打印是1475236
说在最后
js的事件循环有三个队列,都是遵循先进先出的规则,调用栈Stack、宏任务队列macroQuene、微任务队列microQuene,一般执行先执行同步任务,遇到宏任务将其加入宏任务队列,遇到微任务将其加入微任务队列,执行阶段是执行同步-》执行微任务-》执行宏任务
promise
promise简单理解为创建了一个类,定义了状态,resolve和reject函数,利用callback特性,当调用resolve和reject的时候,返回
const PENDING = 'PENDING';
const RESOLVED = 'RESOLVED';
const REJECTED = 'REJECTED';
class Promise {
constructor(executor) {
this.status = PENDING; // 宏变量, 默认是等待态
this.value = undefined; // then方法要访问到所以放到this上
this.reason = undefined; // then方法要访问到所以放到this上
let resolve = (value) => {
if (this.status === PENDING) {// 保证只有状态是等待态的时候才能更改状态
this.value = value;
this.status = RESOLVED;
}
};
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECTED;
}
};
// 执行executor传入我们定义的成功和失败函数:把内部的resolve和reject传入executor中用户写的resolve, reject
try {
executor(resolve, reject);
} catch(e) {
console.log('catch错误', e);
reject(e); //如果内部出错 直接将error手动调用reject向下传递
}
}
then(onfulfilled, onrejected) {
if (this.status === RESOLVED) {
onfulfilled(this.value);
}
if (this.status === REJECTED) {
onrejected(this.reason);
}
}
}
module.exports = Promise;