我有一个流程,我需要非常可控地执行代码的异步部分。具体来说,我有一个node
个项目的链接列表,每个项目都必须按照它们在链接列表中出现的顺序进行评估。但是,某些类型的节点需要评估异步调用。所以,我这样做:
function getTheValueOfOneNodeThatMayNeedAnSyncCall (oneNode) {
return new Promise (function (resolve, reject) {
if (isSpecialTypeThatNeedsAsyncCall (oneNode)) { // Function TBD
oneAsyncCallDefinedInAModule (oneNode) // Function TBD,
returns promise
.then (function (result) {
resolve (result);
})
.catch (function (error) {
reject (new Error ("The async call could not be evaluated"));
});
} else {
resolve (oneNode);
}
});
};
function evaluateAStackInOrder (pSimpleExpression) {
// pSimpleExpression E.g.: node1->node2->node3->node4->node5->null (a linked list)
var computedAsyncsInOrder = [];
var result = false;
let oneNodeProcessedPromise = Promise.resolve ();
pSimpleExpression.traverse (function (oneNode) {
oneNodeProcessedPromise = oneNodeProcessedPromise.
then (function () {
getTheValueOfOneNodeThatMayNeedAnSyncCall (oneNode)
.then (function (nodeVal) {
computedAsyncsInOrder.push (nodeVal);
console.log ("Pushed " + nodeVal + " and stack is now " + computedAsyncsInOrder);
return;
})
.catch (function (error) {
console.log ("Error:\n" + error.message);
return;
});
})
.catch (function (error) {
console.log ("Error processing this oneNode");
return;
});
}); // End of pSimpleExpression.traverse ();
// Compute the final result
oneNodeProcessedPromise.
then (function () {
result =
computeTheFinalResultFromOrderedAsyncs (computedAsyncsInOrder);
return;
})
.catch (function (error) {
console.log ("Error processing final result of Simple expression");
});
return result;
};
我遇到的问题是调用没有按顺序执行。具体来说,无需等待异步调用完成(它们通过REST调用调用request
来评估节点值),程序将运行完成,从而导致错误结果。
有关正在发生的事情的指示?我的承诺构建链接执行顺序是否正确?
答案 0 :(得分:3)
使用ES7的Async
和Await
以及递归,此操作会更清晰。
文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
假设您不需要返回任何内容,您可以执行以下操作:
async function executeInOrder(myLinkedList) {
// if head is null (falsey)
if (!myLinkedList.head)
return;
// Halt execution until this operation is done
await myLinkedList.head.possibleAsyncFunction();
// Set the new head
myLinkedList.head = mylinkedList.head.next;
// Again...
return executeInOrder(myLinkedList);
}
然后你可以使用它:
executeInOrder(myLinkedList)
.then(() => doSomethingAfterwards())
.catch((err) => handleError(err));
或者,如果您只有一个需要循环的节点列表,您可以这样做:
async function executeInOrder(list) {
await Promise.all(list.map(async (node) => {
await node.possibleAsyncFunction();
}));
}