如何在JavaScript中迭代多个异步等待函数并链接在一起?
我是JavaScript和Node.js的新手。我有以下代码:如何在JavaScript中迭代多个异步等待函数并链接在一起?,javascript,node.js,Javascript,Node.js,我是JavaScript和Node.js的新手。我有以下代码: const populateSetup = async () => { token = await getToken(); const promises = await constant.accounts.map(async (x) => { const accountId = await createAccountRequest(x.account); const peoid = awai
const populateSetup = async () => {
token = await getToken();
const promises = await constant.accounts.map(async (x) => {
const accountId = await createAccountRequest(x.account);
const peoid = await createPeopleRequests(x.people);
const pid = await createProjectsRequests(x.project);
return [accountId, pid, peoid];
});
const [accountId, pid, peoid] = await Promise.all(promises);
};
在上面的示例中,首先获取令牌,创建帐户需要令牌,然后返回accountId以创建人员和项目。假设我有以下输入:
exports.accounts = [
{ account: this.testAccountFirst, project: this.projectOne, people: this.testUserOne },
{ account: this.testAccountSecond, project: this.projectTwo, people: this.testUserTwo },
];
在节点环境中运行populateSetup()
后,我的结果是(不是控制台输出,而是populateSetup()
的输出):
预期结果是:
testAccountFirst should have 1 project and 1 people -> projectOne, testUserOne
testAccountSecond should have 1 project and 1 people -> projectTwo, testUserTwo
这里的问题是,第一个帐户的accountId没有发送到projectsRequest。我不知道如何解决此问题。我已经完成了此过程,但仍然无法理解。我很难准确理解您提出的问题,但是
.map()
不懂异步。这意味着即使您将回调声明为async
,.map()
不会对返回的promise执行任何操作,因此它不会在第一次迭代完成之前等待第二次迭代的开始。因此,您最终会并行运行循环所有迭代中的所有异步操作,并且它们可以以任意随机顺序完成
如果您真的想一个接一个地顺序运行它们,那么请将
.map()
切换到for
循环,因为for
循环将在循环的第一次迭代中等待等待,然后再开始循环的第二次迭代,依此类推……返回[accountId,pid,peoid];
正在返回已解决的承诺,并且,您需要等待一个承诺的解决。例如,如果一个解决是5秒,那么您需要等待5+5+5=15秒
但更重要的是,使用带有内部承诺的.map()
,这是一种不好的做法,因为它是sync操作符。
在你的情况下,我会用这样的方式:
const populateSetup = async () => {
const token = await getToken();
const [accountId, peoid, pid] =[
createAccountRequest(x.account),
createPeopleRequests(x.people),
createProjectsRequests(x.project)
]
return Promise.all([accountId, peoid,pid])
};
在这里,您返回承诺,可以这样使用:
const[accountId,peoid,pid]=wait populateSetup()
Promise.all()
请同时执行Promise并等待所有问题得到解决,因此您的等待Promise的时间是5秒,而不是15秒。all()
是一个数组,其中数组中的每个元素都是[accountId,pid,peoid]
。还有.map()
并行运行所有异步操作。第二次迭代直到第一次迭代完成才开始。如果您想一次运行一次,请使用常规的for
循环。感谢@jfriend00使用for loop
为我工作。虽然答案是正确的,for loop是解决方案之一,但我很难做到这一点假设console.log(accountId、pid、peoid)在任何情况下,
都会先打印TestAccount,testUserOne
。它总是打印3个值,空格分隔,即使其中一个值是未定义的
。永远不会打印4个值,也不会打印逗号。请更新您的问题,以便下次阅读时不会感到困惑。@AlexPakka-编辑了我的问题,很抱歉是的,我很抱歉由于一个循环的返回依赖于另一个循环,所以继续顺序执行。for
循环对我来说确实有效。谢谢,我理解你的意思。在我的情况下,我正在寻找顺序执行,所以Promise
似乎对我不起作用。
const populateSetup = async () => {
const token = await getToken();
const [accountId, peoid, pid] =[
createAccountRequest(x.account),
createPeopleRequests(x.people),
createProjectsRequests(x.project)
]
return Promise.all([accountId, peoid,pid])
};