非同期操作を使用して特定のノードで操作を実行するには、ツリーを再帰する必要があります。完了時にノードにアクセスできるようにフローを制御するにはどうすればよいですか?
状況の例を次に示します。
data = {
name: "deven",
children: [
{ name: "andrew" },
{ name: "donovan" },
{ name: "james",
children: [
{ name: "donatello" },
{ name: "dan" }
]
},
{ name: "jimmy",
children: [
{ name: "mike" },
{ name: "dank" }
]
}
]
};
ツリーを反復処理し、「d」で始まるすべての名前を大文字にすることを目標とする関数があります。その後、ツリーを別の関数に渡してさらに作業を行います (「a」で始まる名前を持つすべてのノードを削除する可能性があります) が、最初の処理が完了した後でのみ行います。
function capitalize_d(node) {
if(node.name === "d") {
node.name = node.name.toUpperCase();
}
if(node.children != null) {
for(var i = 0; i < node.children.length; i++) {
capitalize_d(node.children[i]);
}
}
}
function remove_a(node) {
}
capitalize_d(data);
// Should only get called after all the d's have been capitalized.
remove_a(data);
capitalize_d がブロックしているため、上記のコードは問題なく動作します。capitalize_d
非同期に再帰する場合、完了remove_a
後に呼び出されることをどのように保証できますか? setTimeout
の呼び出しに注意してくださいcapitalize_d
。
function capitalize_d(node) {
setTimeout(function() {
if(node.name === "d") {
node.name = node.name.toUpperCase();
}
if(node.children != null) {
for(var i = 0; i < node.children.length; i++) {
capitalize_d(node.children[i]);
}
}
}, 1);
}
function remove_a(node) {
}
capitalize_d(data);
// Should only get called after all the d's have been capitalized.
remove_a(data);
問題は、ツリーのさまざまなブランチの処理がすべて同時に開始され、最終的にいつツリーの処理が完了したかを判断できないことです。
どうすればこれを解決できますか?