2014-11-08 102 views
2

我假設Q.all([p1, p2, p3]).then(f)是沒有什麼不同爲什麼Q.all像這樣執行?

p1.then(function() { 
    p2.then(function() { 
     p3.then(f); 
    }); 
}); 

因爲當p1p2p3創建的異步調用已經作出,我們只需要等待他們都解決和沒有按順序沒關係。

我正確嗎?

如果是這樣,我一直在尋找kriskowal's all implementation。我認爲這會是類似的事情(鏈接承諾使用then)。但我發現它的實施方式完全不同?這是爲什麼?

編輯:

讓我更加清楚一點。說p1,p2,p3分別在100ms,200ms,300ms解析。等待他們的反應順序不作任何differens

p1.then(function() { 
    // we're here at 100ms 
    p2.then(function() { 
     // 100ms later we're here 
     p3.then(f); // f gets called 100ms later (at 300ms) 
    }); 
}); 

p3.then(function() { 
    // we're here at 300ms 
    p2.then(function() { 
     // boom! resolves in a snap 
     p1.then(f); // f also gets called instantly (at 300ms) 
    }); 
}); 

在這兩個例子中,我們只能等待所有三項承諾300ms的解決。

回答

4

我假設Q.all([p1, p2, p3]).then(f)是沒有什麼不同

p1.then(function() { 
    p2.then(function() { 
     p3.then(f); 
    }); 
}); 

不完全是。 f正在通過一系列結果,並且您總是希望return(承諾)結果;所以你會寫

p1.then(function(r1) { 
    return p2.then(function(r1) { 
     return p3.then(function(r3) { 
      return f([r1, r2, r3]); 
     }); 
    }); 
}); 

// or equivalently, better matching a separate `Q.all`: 
p1.then(function(r1) { 
    return p2.then(function(r1) { 
     return p3.then(function(r3) { 
      return [r1, r2, r3]; 
     }); 
    }); 
}).then(f); 

因爲當P1,P2和P3產生的異步調用已經 而做出的,我們只需要等待他們都解決和 爲了不物。

我正確嗎?

有點。的確,.all的天真版本可以像這樣實施。然而,我們需要看一個重要的「邊緣」情況:當承諾沒有得到履行但被拒絕時。突然之間,回調的嵌套結構就變成了錯誤 - 因爲我們想要平行並從頭看所有三個承諾。假設p3在200ms後解析,p1在300ms後解析,p2在100ms後被拒絕。

使用嵌套的then回調函數,它會在第一次觀察p2之前等待整個300ms(p1) - 但是,它早已被拒絕。相反,.all方法想要提前失敗,並拒絕結果承諾,只要任何被拒絕。

因此(和一點性能),Q.all內部使用deferred pattern

0

沒有。他們是不同的。

在這裏,你認爲p2只會在p1完成後纔開始。並且p2只在p2完成之後。

p1.then(function() { 
    p2.then(function() { 
     p3.then(f); 
    }); 
}); 

所以基本上,你介紹了序列和依賴。做1,然後2,然後3.如果p3取決於p2的結果並且p2取決於p1的結果,則這是理想的。但是,這會給代碼帶來很多複雜性和依賴性,所以您最好謹慎使用它。甚至儘可能地避免它。

以下,但是,不需要序列:

Q.all([p1, p2, p3]).then(f) 

F由所有3是成品(P1,P2和P3),但有三者之間無交叉依賴性。 p2可能會先完成,然後是p1或p3(它們是異步完成的)。不需要訂單。唯一的要求是所有三個都按照f的任何順序完成。總的來說,如果可能的話,這會更好。 p2和p3不必等到p1完成後纔開始發出請求或處理任何內容。

希望我回答你的問題:)

+1

謝謝你的回答,但我認爲你錯了。我認爲,當我們有p1和p2以及p3時,意味着所有三個請求都已發送,我們只是在等待他們的迴應。我們「等待」的順序並不重要。這不像我們發送p1,等待響應,然後發送p2。 – adm 2014-11-08 11:44:50

+0

@Arthur:請注意'p1','p2','p3'是承諾,而不是創建承諾的調用。 – Bergi 2014-11-08 13:25:22

+0

真的!你的解釋很棒:) – 2014-11-08 19:10:14