Jun*_*ang 7 javascript callstack event-loop
我正在学习Promise,为了理解它我读了一些关于JavaScript的事件循环.此文章简要介绍了事件循环的工作,如调用堆栈,事件表和消息队列.
但我不知道调用堆栈如何处理包含'return'的行,以及之后会发生什么.下面是我写的一个例子,希望了解Promise如何基于事件循环工作.如果你想试一试,请参阅http://jsbin.com/puqogulani/edit?js,console.
var p1 = new Promise(
function(resolve, reject){
resolve(0);
});
p1.then(function(val){
console.log(val);
p1.then(function(){
console.log("1.1.1");
p1.then(function(){
console.log("1.1.2");
p1.then(function(){
console.log("1.1.3");
});
});
});
p1.then(function(){
console.log("1.2");
})
return 30;
//return new Promise(function(resolve, reject){
// resolve(30);
//});
})
.then(function(val){
console.log(val/2);
});
p1.then(function(){
console.log("2.1");
});
console.log("Start");
Run Code Online (Sandbox Code Playgroud)
可以看出,有两个"返回",使用它们中的每一个都会给出不同的输出顺序.具体来说,使用时return 30;,1.1.2, 1.1.3都是经过15,但使用的时候return new Promise(...),1.1.2, 1.1.3是前15.那么当代码达到两个不同的"返回"时究竟发生了什么?
http://promisesaplus.com/中的承诺解决程序下描述了差异。
对于第一个返回值:
2.3.3.4 如果 then 不是函数,则用 x 履行promise。
对于第二个:
2.3.2 如果 x 是一个promise,则采用它的状态[3.4]:
2.3.2.2 如果/当 x 被履行时,以相同的值履行承诺。
我们可以看到这个实现了q.js。这是一种可能的实现,但似乎可以解释延迟:
function coerce(promise) {
var deferred = defer();
Q.nextTick(function () {
try {
promise.then(deferred.resolve, deferred.reject, deferred.notify);
} catch (exception) {
deferred.reject(exception);
}
});
return deferred.promise;
}
Run Code Online (Sandbox Code Playgroud)
当从函数返回一个 Promise 时then,我们有两个独立的 Promise 对象:一个从传递给 的函数返回then,一个从 传回then。这些需要连接在一起,以便解决第一个,解决第二个。这是用完成的promise.then(deferred.resolve, ...)
第一个延迟来自Q.nextTick. 这将在事件循环的下一次迭代中执行该函数。提交评论中有一些关于为什么需要它的讨论。
调用promise.then会进一步延迟事件循环的一次迭代。根据规范要求:
2.2.4 在执行上下文堆栈仅包含平台代码之前,不得调用 onFulfilled 或 onRejected。[3.1]。
执行过程会是这样的:
p1.then with function containing 1.1.1 is called
function containing 1.1.1 is queued
p1.then with function containing 1.2 is called
function containing 1.2 is queued
Promise resolving to 30 is returned
Q.nextTick function is queued
----------
1.1.1 is printed
p1.then with function containing 1.1.2 is called
function containing 1.1.2 is queued
1.2 is printed
Q.nextTick function is executed
promise.then(deferred.resolve, ...) is queued
----------
1.1.2 is printed
p1.then with function containing 1.1.3 is called
function containing 1.1.3 is queued
promise.then(deferred.resolve, ...) is executed
function containing val/2 is queued
----------
1.1.3 is printed
val/2 is printed
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |