Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在JavaScript中迭代多个异步等待函数并链接在一起?_Javascript_Node.js - Fatal编程技术网

如何在JavaScript中迭代多个异步等待函数并链接在一起?

如何在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

我是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 = 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])
};