[JS] 异步事件及promise运行机制探究

Posted DiracKeeko

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JS] 异步事件及promise运行机制探究相关的知识,希望对你有一定的参考价值。

事件分为

1、同步事件
2、异步事件 异步事件又被分为 宏任务 微任务

宏任务
1、新程序或子程序被直接执行,如<script>标签里的代码是程序被直接执行,控制台写代码也算程序直接执行。
2、事件的回调函数,如onClick, onKeyup的回调函数。
3、setTimeout()和setInterval()里面的回调函数。
其他: I/O操作,UI rendering,requestAnimationFrame,setImmediate

微任务
1、Promise .then() .catch() .finally()
2、以及node.js里的process.nextTick()

其他:Object.observe等

同一个任务,在一个浏览器中可能被归为宏任务在另一浏览器中可能被归为微任务。
有些浏览器会把Promise.then()归为宏任务,主流的归类方式就是微任务。

宏任务和微任务的执行需要 Event Loop 事件循环
Event Loop会不断寻找可执行的任务来执行,在执行完同步任务之后
1、首先会执行微任务队列的任务,把微任务队列的任务清空之后才会去执行宏任务 (保证效率)
2、浏览器渲染(如果有)。
3、执行宏任务。
4、重复1 2 3

知道了上面的宏任务、微任务分类,再往下看实例
/*

setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
resolve();
console.log("3");
}).then(() => {
console.log("4");
}).then(() => {
console.log("5");
})
console.log("6");
*/
// 上面代码块的输出结果 2 3 6 4 5 1

/*
setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
// 没有明确的结果
console.log("3");
}).then(() => { // then() 不执行
console.log("4");
}).then(() => {
console.log("5");
})
console.log("6");
*/
// 上面代码块的输出结果 2 3 6 1

/*
setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
reject();
console.log("3");
}).catch(() => {
console.log("4")
}).then(() => {
console.log("5");
})
console.log("6");
*/
// 上面代码块的输出结果 2 3 6 4 5 1

/*
setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
reject();
console.log("3");
}).catch(() => {
console.log("4"); // 进入这个catch (因为new Promise的状态是rejected)
}).catch(() => {
console.log("5"); (但是这里没有rejected了,所以不会输出5)
})
console.log("6");
*/
// 上面代码块的输出结果 2 3 6 4 1

/*
setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
reject();
console.log("3");
}).catch(() => {
console.log("4")
reject();
}).catch(() => {
console.log("5");
})
console.log("6");
*/
// 上面代码块的输出结果 2 3 6 4 5 1

/*
setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
reject();
console.log("3");
}).catch(() => {
console.log("444");
reject();
console.log("4")
}).catch((a) => {
console.log("5");
})
console.log("6");
*/
// 上面代码块的输出结果 2 3 6 444 5 1
// 不同于new的过程,实例中,reject()之后就不会往下执行

/*
setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
resolve();
console.log("3");
}).catch(() => {
console.log("4")
}).then(() => {
console.log("5");
})
console.log("6");
*/
// 上面代码块的输出结果 2 3 6 5 1
// 这部分的代码块,
// catch 和 then 都是Promise构造函数的直接后方,
// 不是.catch().then()这样的链式调用

/*
setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
reject();
console.log("3");
}).catch(() => {
console.log("4");
reject("rejected");
}).catch((a) => {
console.log(a); // 此处会报错
console.log("5");
})
console.log("6");
*/

// 上面代码块的输出结果 ↓
/*
2
3
6
4
ReferenceError: reject is not defined
5
1
*/
// 除非直接在Promise构造函数内部,否则不能调用reject,因为它不在作用域内。

/*
setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
setTimeout(() => {resolve();}) // 宏任务
console.log("3");
}).then(() => {
console.log("4");
}).then(() => {
console.log("5");
})
console.log("6");
*/
// 上面代码块的输出结果 2 3 6 1 4 5

/*
setTimeout(() => {
console.log("1");
})
new Promise((resolve, reject) => {
console.log("2");
return;
console.log("3");
resolve();
}).then(() => {
console.log("4");
}).then(() => {
console.log("5");
})
console.log("6");
*/
// 上面代码块的输出结果 2 6 1
// return结束了promise的构造函数

同步更新在自己的语雀
https://www.yuque.com/diracke...

以上是关于[JS] 异步事件及promise运行机制探究的主要内容,如果未能解决你的问题,请参考以下文章

对javascript EventLoop事件循环机制不一样的理解

js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)

js运行机制 (包括宏任务微任务,同步异步,事件循环机制Event Loop)面试常问

前端基础 | JS异步执行机制——事件循环(Event Loop)

js事件循环运行机制

js事件循环运行机制