[英]Q - executing a series of promises and defining dependencies between them in a DAG
我想處理一系列數據,其中每個數據的輸出可以用作其他數據的輸入。
例如:
var batch = [
{"id":"a1","depends":[],"data":{"some":"data a1"}},
{"id":"b1","depends":["a1"],"data":{"some":"data b1"}},
{"id":"b2","depends":["a1"],"data":{"some":"data b2"}},
{"id":"c1","depends":["b1","b2"],"data":{"some":"data c1"}},
{"id":"x1","depends":[],"data":{"some":"data x1"}},
];
這意味着一旦a1
完成,其輸出將被發送到b1
和b2
; 當這些完成時,它們的兩個輸出都將被發送到c1
(僅在它們完成時兩個x1
可以與所有a1
, b1
, b2
和c1
並行執行;並且b1
可以與b2
並行執行,因為no depends
它們之間的定義。
完成c1
和x1
,並因此完成所有5個后,應返回所有五個的輸出。
我們假設沒有定義循環依賴,因此是有向無環圖(DAG)
我想知道如何使用Q實現這個,因為:
但是,我未能將這個過去概念階段
var doPromises = {};
var doData = function(data, dependsResultsHash, callback) {
//Not real processing, simply echoes input after a delay for async simulation purposes
var out = {
echo: {
data: data,
dependsResultsHash: dependsResultsHash
}
};
setTimeout(function() {
callback(out);
}, 1000);
};
var doLine = function(id, depIds, data) {
var deferred = Q.defer;
var dependsPromises = [];
for (var i = 0; i < depIds.length; ++i) {
var depId = depIds[i];
dependPromise = doPromises[depId];
dependsPromises.push(dependPromise);
}
Q.all(dependsPromises).then(function(dependsResults) {
var dependsResultsHash = {};
for (var i = 0; i < depIds.length; ++i) {
var depId = depIds[i];
var depResult = dependsResults[i];
dependsResultsHash[depId] = depResult;
}
doData(data, dependsResultsHash, function(result) {
deferred.resolve(result);
});
});
return deferred.promise;
}
var doBatch = function(batch) {
var linePromises = [];
for (var i = 0; i < batch.length; ++i) {
var line = batch[i];
var linePromise = doLine(line.id, line.depends, line.data);
linePromises.push(linePromise);
doPromises[line.id] = linePromise;
}
Q.all(linePromises).then(function(lineResults) {
console.log(lineResults);
deferred.resolve(lineResults);
});
};
doBatch(batch);
(請注意,此代碼未經測試,我認為它不起作用,只是為了說明我的問題所必需的點。)
我想知道:
Q
庫的重點。 還是延期和承諾? 我主要關心的是doData
函數:
-- Is the way that I have selected the promises of the lines depended upon from the global list of promises `doPromises` ok? -- Is the way that I have obtained the results of the lines depended upon, and inpterpreted that OK?
使用doBatch
函數:
-- I have a local array for `linePromises` and an external hash for `doPromises`, and I feel that these should be combined. How can I do this correctly?
一般
-- The code above presently assumes that all `deferred`s will eventually keep their `promise`s. What if they fail or throw an exception; how do I make my code more robust in handling this? -- I have used a closure allow acces to `doPromises` in both `doBatch` and `doLine`, and it seems a little odd here, is there a better way to do this?
我創建了一個執行此操作的庫:
qryq是一個NodeJs庫,它允許表達一系列查詢並在它們之間並行,按順序或在有向非循環圖中定義它們之間的依賴關系。
我最近創建了一個名為dagmise的模塊,我計划用它來構建一個使用promises作為任務的構建系統。 我最終制作了返回promises的圖形函數的節點。 訪問節點時,將評估其中的函數,並且返回的promised將其作為節點的值。 因此,即使多次訪問節點,該函數也只執行一次。
我開始認為承諾應該是邊緣,但現在我認為將它們放在節點上更簡單。 否則你最終會在圖形中出現兩種對象(節點/狀態和邊緣/承諾),這會使事情變得復雜。
我剛剛為此實現了自己的庫: promise-dag 。
由於以下原因,我對提到的替代品( dagmise
, qryq
)不滿意:
promise-dag
與任何Promise實現兼容,沒有任何代碼依賴。 _.extend()
, _.pick()
,...)組合計算圖,以及添加自定義檢測(分析/跟蹤/記錄/等)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.