JavaScript执行机制

JavaScript 执行(一):Promise 里的代码为什么比 setTimeout 先执行?

宏观任务的队列就相当于事件循环。在宏观任务中,JavaScript 的 Promise 还会产生异步代码,JavaScript 必须保证这些异步代码在一个宏观任务中完成,因此,每个宏观任务中又包含了一个微观任务队列

Promise 永远在队列尾部添加微观任务。setTimeout 等宿主 API,则会添加宏观任务。

Event Loop

1
2
3
4
5
6
7
var r = new Promise(function (resolve, reject) {
console.log('a');
resolve();
});
setTimeout(() => console.log('d'), 0);
r.then(() => console.log('c'));
console.log('b');

//输出 a b c d 我们发现,不论代码顺序如何,d 必定发生在 c 之后,因为 Promise 产生的是 JavaScript 引擎内部的微任务,而 setTimeout 是浏览器 API,它产生宏任务。

异步执行的顺序:首先我们分析有多少个宏任务;在每个宏任务中,分析有多少个微任务;根据调用次序,确定宏任务中的微任务执行次序;根据宏任务的触发规则和调用次序,确定宏任务的执行次序;确定整个顺序。

宏任务:setTimeout 是浏览器 API,它产生宏任务。

微任务:Promise 永远在队列尾部添加微观任务。

1
2
3
4
5
6
7
8
function sleep(duration) {
return new Promise(function (resolve, reject) {
console.log('b');
setTimeout(resolve, duration);
});
}
console.log('a');
sleep(5000).then(() => console.log('c'));

setTimeout 把整个代码分割成了 2 个宏观任务。

第一个宏观任务中,包含了先后同步执行的 console.log(“a”); 和 console.log(“b”);。

setTimeout 后,第二个宏观任务执行调用了 resolve,然后 then 中的代码异步得到执行,最终输出的顺序才是: a b c。

新特性:async/await

async 函数必定返回 Promise,我们把所有返回 Promise 的函数都可以认为是异步函数。

async 表示函数里有异步操作; await 表示紧跟在后面的表达式需要等待结果。

async 返回一个 Promise 对象,可以用 then 来添加回调函数,

JavaScript 执行(三):你知道现在有多少种函数吗?

this

调用函数时使用的引用,决定了函数执行时刻的 this 值。

1
2
3
4
5
6
7
8
9
10
function showThis() {
console.log(this);
}

var o = {
showThis: showThis,
};

showThis(); // global
o.showThis(); // o

改为箭头函数后,不论用什么引用来调用它,都不影响它的 this 值

1
2
3
4
5
6
7
8
9
10
const showThis = () => {
console.log(this);
};

var o = {
showThis: showThis,
};

showThis(); // global
o.showThis(); // global

生成器函数、异步生成器函数和异步普通函数跟普通函数行为是一致的,异步箭头函数与箭头函数行为是一致的。

1
2
3
4
5
6
7
8
9
10
class C {
showThis() {
console.log(this);
}
}
var o = new C();
var showThis = o.showThis;

showThis(); // undefined
o.showThis(); // o

0334b3bc171a489654ea5a37f47c34d8.png 8c7bd55633bb59c3a3547e41c14ac876.png

极客时间版权所有: https://time.geekbang.org/column/article/88538

  • symbol

掘金文章

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2018-2020 Jee
  • Visitors: | Views:

如果您觉得此文章帮助到了您,请作者喝杯咖啡吧~

支付宝
微信