[英]Serialized Execution of an Array of Promise Chains in Bluebird
我正在嘗試構建一系列 Promises 鏈並讓它們按順序執行。 每個鏈在數組中的下一個條目執行之前完成。 例如: [connect1, connect2, connect3]
其中每個“任務”包含一定數量的步驟鏈。
我遇到的大問題之一是能夠構建鏈並將其添加到數組中——因為它已經開始執行。
我一直在玩的一些測試代碼在這里:
function step1() {
return new Promise(resolve => {
// Normally something asnyc here
console.log("step1:", this);
resolve();
});
}
function step2() {
return new Promise(resolve => {
// Normally something asnyc here
console.log("step2:", this);
resolve();
});
}
function step3() {
return new Promise(resolve => {
// Normally something asnyc here
console.log("step3:", this);
resolve();
});
}
function promiseSeq( tasks, state ) {
let current = Promise.resolve();
for (let k = 0; k < tasks.length; ++k) {
var taskWithState = tasks[k];
if (typeof state !== 'undefined') {
taskWithState = taskWithState.bind(state);
}
current = current.then(taskWithState);
}
return current;
}
function buildChain(idx) {
// Build the connection chain (with state)
//------------------------------
var s = { conn: idx }; // some state
var q = [ step1, step2, step3 ];
return promiseSeq(q, s);
}
function streamConnect() {
// Build array of chains
//------------------------------
var q = [ ];
q.push(buildChain(1)); // e.g. connect1
q.push(buildChain(2)); // e.g. connect2
q.push(buildChain(3)); // e.g. connect3
var p = Promise.each(q, function(f) {return ( f )});
// Process promises...
p.then(function() {console.log("done")})
.catch(function(err) {console.error("catch:",err)})
return;
}
一旦我擁有數組中每個“任務”的鏈,我想按順序執行鏈。 所以我的目標是讓輸出為:
step1: Object {conn: 1}
step2: Object {conn: 1}
step3: Object {conn: 1}
step1: Object {conn: 2}
step2: Object {conn: 2}
step3: Object {conn: 2}
step1: Object {conn: 3}
step2: Object {conn: 3}
step3: Object {conn: 3}
而是使用我的代碼,我看到:
step1: Object {conn: 1}
step1: Object {conn: 2}
step1: Object {conn: 3}
step2: Object {conn: 1}
step2: Object {conn: 2}
step2: Object {conn: 3}
step3: Object {conn: 1}
step3: Object {conn: 2}
step3: Object {conn: 3}
當談到 Promises 時,我非常綠色,我試圖理解(沒有特定的順序): 1. 為什么 Promise 執行似乎是交錯的(所有 step1 都完成了,然后是 step2 等等)? 2. 如何在上面的預期輸出中獲得序列化的執行行? 3. 鏈可以以延遲方式設置嗎? 我看到我的行current = current.then(taskWithState);
最終使用 Bluebird 調用async.invoke
,但我沒有找到避免這種情況的方法。
任何建議或幫助將不勝感激。
您的buildChain()
函數執行您的操作。 它立即開始運行它們。
所以,這段代碼:
var q = [ ];
q.push(buildChain(1)); // e.g. connect1
q.push(buildChain(2)); // e.g. connect2
q.push(buildChain(3)); // e.g. connect3
立即開始運行所有三個鏈。 因此,您有三個並行運行的承諾鏈,而不是按順序運行。
僅供參考,這行代碼應該是一個有趣的線索:
var p = Promise.each(q, function(f) {return ( f )});
因為當Promise.each()
調用它的回調時,你實際上並沒有做任何事情。 因此,您沒有賦予它任何對您的操作的控制權。 它們甚至在Promise.each()
運行之前就已經啟動了。
您可以使用Promise.each()
來解決此問題,但您需要按預期使用它。 它希望你向它傳遞一個數組和一個對數組中的項目進行操作的迭代器。 你不會做那樣的事情。 您正在向它傳遞一組已經開始執行的承諾。
您可以通過將streamConnect()
更改為streamConnect()
來修復它:
function streamConnect() {
var q = [1,2,3];
var p = Promise.each(q, function(item) {
return buildChain(item);
});
// Process promises...
p.then(function() {console.log("done")})
.catch(function(err) {console.error("catch:",err)})
return;
}
這不會開始執行由Promise.each()
調用的每個鏈 UNTIL。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.