js进入es6后,对于异步操作进行了很多友好的改善,如Promise,async,await等特性:
在使用Promise时,我经常疑惑它内部的执行顺序,以及它到底包装了什么,经过多次的尝试和验证,得出了一些自己的见解,在此和大家分享一下。
大家首先要知道:
1、JS是单线程语言,包括同步任务、异步任务、异步任务又包括宏观任务和微观任务
2、执行顺序:同步任务——>微观任务——>宏观任务
3、Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值
大家先来看这个脚本,
console.log(0); // js线程自上而下执行脚本
const promise = new Promise((resolve, reject) => {
// resolve('梗');
console.log(1); // promise内部语句同步执行
setTimeout(() => { // 遇到异步语句放入异步栈后继续向下执行
console.log(4); // 线程运行完毕开始执行异步栈中的语句
resolve('foo');
console.log(5);
}, 2000);
});
console.log(2);
promise.then((value) => {
console.log(value, 6); // promise回调承诺
});
console.log(promise, 3);
执行结果为:
如果上个脚本对你很好理解的话,那么我如果放开注释“梗”,结果又如何呢?大家不妨先想3秒钟再往下看
3,
2,
1
现在大家就很容易看出来了,Promise只影响内部resolve及reject自身钩子的代码语句,非钩子语句的执行顺序可无视Promise的包装,因为没有任何影响,另外大家也能看出Promise包装的异步是微观任务,在setTimeout等宏观异步之前执行。
下面附赠利用primise,和es6的async,await实现线程睡眠sleep函数
// 利用primise,和es6的async,await实现线程睡眠sleep函数
(async () => {
console.log('begin');
const sleep = (sec) => {
return new Promise((res, rej) => {
setTimeout(() => {
console.log('sleep:' + sec + 'ms');
res(sec); // 如不执行结果回调,await后续语句将不会执行
}, sec)
})
}
await sleep(2000);
console.log('end');
})()