new Promise executor的执行时机
new Promise里面通常会传入一个function参数。直觉上,传入的function,应该类似于callback,属于被异步调用的。但是实际上,它是同步被执行的。也就是说它是在Promise的构造函数里面被执行的。文献
https://javascript.info/promise-basics提到这个function有个专有的名字:executor:
The function passed to new Promise is called the executor. When new Promise is created, the executor runs automatically.
下面看看一个http request(https://developers.google.com/web/fundamentals/primers/promises)。new promise里面的XMLHttpRequest是即时发出的。所谓异步,体现在Promise.then的执行,是在onload/resolve之后发生的。
function get(url) {
// Return a new promise.
return new Promise(function(resolve, reject) {
// Do the usual XHR stuff
console.log("In Promise's executor");
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
// This is called even on 404 etc
// so check the status
if (req.status == 200) {
// Resolve the promise with the response text
resolve(req.status);
}
else {
// Otherwise reject with the status text
// which will hopefully be a meaningful error
reject(Error(req.statusText));
}
};
// Handle network errors
req.onerror = function() {
reject(Error("Network Error"));
};
// Make the request
req.send();
});
}
console.log("Begin");
get('https://jsfiddle.net/').then(function(response) {
console.log("Success!", response);
}, function(error) {
console.error("Failed!", error);
})
console.log("End");
Begin
In Promise's executor
End
Success! 200
Promise.then的执行时机
Promise.then里面的函数,其执行时机是主线程结束后的某个时间。
关于promise的执行有两种猜测:
- chromium里面维护了多个线程,操作DOM所在的JS线程叫主线程。此外为了实现异步,准备了一个线程池,这个线程池,就是用于执行这里的promise的任务。
- (作者更倾向于这个)Promise和操作DOM的JS都位于同一个主线程(我理解JS是单线程的,Promise也并没有和WebWorker绑定)。在Chromium内部,每次碰到Promise,都会给主线程post 一个task。chromium内部线程机制是,post task是在下一个时钟周期开始执行里面的任务的(每次时钟周期开始会切换任务队列)。所以我们能够观测到,所有Promise,都是在主线程把所有事情做完后的某个时机,才开始逐个被resolve的。要验证Promise是否是在主线程的方法是:在Promise里面执行一个超长的任务,看看网页UI是否失去响应(TODO)。
var promise1 = new Promise(function(resolve, reject) {
// 输出1
console.log("Ins