2017-08-13 18 views
0

實現了承諾隊列(通過q庫)。承諾隊列中的Async.waterfall未能顯示縮進行爲

PQFn1-(然後) - PQFn2-(然後)-....

的PQFn1傳遞值的回調函數(使用Q.defer實現),它返回一個結果的數組。 所以從PQFn1到ProcessResultFn([值]) 內ProcessResultFn-流量開關

ProcessResultFn(values){ 
    var deferred = Q.defer(); 

async.map(values,FetchResult,function(err,res){ 
     if (err) { 
     deferred.reject(err); 
     return deferred.promise; 
    } else { 
     deferred.resolve(res); 
     return deferred.promise; 
    } 
}) 
} 

Function FetchResult(value,done){ 
async.waterfall(Fn1,Fn2,Fn3,done); 
} 
} 

流工作正常,直到呼叫到達Fn1的。然而,只要Fn1調用cb() - 將呼叫傳遞給Fn2。流程切換到承諾隊列的PQFn2,甚至無需等待ProcessResultFn的結果。 稍後,當事件循環接收到(我記錄它)時,Fn2和Fn3的調用也會執行。然而,從PQFn1到PQFn2的初始結果總是返回undefined。 有人可以解釋爲什麼會發生這種情況。

+0

你可以在問題中包含'FN1'的文本嗎? – guest271314

回答

0

你必須從ProcessResultFn函數返回的承諾,而不是從async.map回調:

ProcessResultFn(values) { 
    var deferred = Q.defer(); 
    async.map(values,FetchResult,function(err,res){ 
     if (err) { 
      deferred.reject(err); 
     } else { 
      deferred.resolve(res); 
     } 
    }); 
    return deferred.promise; 
// ^^^^^^^^^^^^^^^^^^^^^^^ 
} 

(當然,我建議不要使用async.js時,你可以有承諾的時候了,所以相當promisify Fn1,Fn2Fn3和簡單使用Q.all(values.map(value => Fn1P(value).then(Fn2P).then(Fn3P)))。)

+0

是的。這讓它工作。 @Bergi我是承諾的新手,所以我的自然本能是在回調函數內部調用返回值(在這種情況下返回deferred.promise),否則會在執行異步函數之前調用它。 爲什麼在這種情況下有所不同? –

+0

因爲'return'只能立即工作,*不*在異步函數內部(就像通常的異步回調一樣)。 Promise是一個數據結構,它允許我們在那裏返回一個*有意義的值,即使還沒有發生任何事情。 – Bergi