それぞれの出力を他のデータへの入力として使用できる一連のデータを処理したいと思います。
例えば:
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
depends
と が完了するc1
とx1
、したがって 5 つすべてが完了すると、5 つすべての出力が返されます。
循環依存関係が定義されていないため、有向非巡回グラフ (DAG) であると仮定します。
Qを使用してこれを実装する方法を知りたいのですが、理由は次のとおりです。
- データの処理はすべて非同期であるため、コールバック、または deferred と promise のいずれかを使用する必要があります。そして私は後者を好みます
- Promise は、グラフのエッジを定義する便利な方法としても機能します。
しかし、私はこれを概念段階を過ぎて取ることができませんでした
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?