2017-01-22 61 views
7

我正在學習Promise,爲了理解它,我閱讀了一些關於JavaScript的Event循環的內容。這個article簡要介紹了事件循環的工作,如調用堆棧,事件表和消息隊列。瞭解已解決承諾的後續then()處理程序的執行順序

但我不知道調用堆棧如何處理包含'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"); 

可以看出,有兩個「迴歸」,利用他們每個人都會給出不同的輸出順序。具體來說,當使用return 30;,1.1.2, 1.1.3後是15,但是當使用return new Promise(...)時,1.1.2, 1.1.315之前。那麼當代碼達到兩個不同的'返回'時到底發生了什麼?

+1

刪除的1.1.4和1.1的回調。5 - 他們沒有被引用,並使其不易理解,每個人都已經達到了1.1.2。沒有他們,每個人仍然能夠理解困境。 –

+0

@ try-catch-finally,感謝您的建議和編輯。我只是想更清楚一點,雖然有時它會讓事情變得相反:) –

+0

So @ try-catch-finally,我想知道你能否就我的問題提出建議?謝謝 –

回答

2

的差在http://promisesaplus.com/下承諾分辨率過程中所述。

對於第一個返回值:

2.3.3.4如果那麼是不是一個功能,實現與X的諾言。

對於第二個:

2.3.2如果x是一個承諾,通過其狀態[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; 
} 

當返回從then功能的承諾,我們有兩個獨立的承諾對象:從傳遞給then的功能之一返回,並從一個返回then。這些需要連接在一起,以解決第一個問題,解決第二個問題。這與promise.then(deferred.resolve, ...)

第一延遲來自Q.nextTick完成。這將在事件循環的下一次迭代中執行該函數。有關commit comments的一些討論,爲什麼需要它。

調用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 
+0

非常感謝你的文章,這是非常清楚地說明我想知道什麼! –