在.map循环内以正确的顺序执行异步请求

时间:2020-10-18 08:02:49

标签: javascript promise async-await request-promise array.prototype.map

我正在努力解决内部的.map循环和异步功能。我将请求承诺用于异步请求。

  import * as rp from 'request-promise';

  const testArray = ['one', 'two', 'three'];
  const link = 'https://somelink.com/';

  const test = testArray.map(async (elem) => {
    console.log('before', elem);

    await rp.get(link)
      .then(async () => {
        console.log('success');
      });

    console.log('after', elem);
  });

  Promise.all(test);

此代码的输出:

before one
before two
before three
success
after one
success
after three
success
after two

我需要的是按正确的顺序执行的代码,其输出如下:

before one
success
after one
before two
success
after two
before three
success
after three

无法弄清楚我在做什么错。请帮忙。

1 个答案:

答案 0 :(得分:1)

.map()不了解async。您传递的回调函数中,它不会暂停await的循环。相反,await会立即使async函数返回一个未解决的Promise,而.map()将继续循环的其他迭代。您似乎已经知道,.map()产生的数组将只是这些承诺的数组。

如果您希望循环暂停并等待await,以便可以真正地对异步操作进行排序,请使用普通的for循环,而不是.map()循环。 / p>

 import * as rp from 'request-promise';

  const testArray = ['one', 'two', 'three'];
  const link = 'https://somelink.com/';

  for (let elem of testArray) {
    console.log('before', elem);

    await rp.get(link)
      .then(async () => {
        console.log('success', elem);
      });

    console.log('after', elem);
  });

这将依次执行您的rp.get()操作,等待第一个操作完成,然后再执行第二个操作。您的.map()循环正在并行执行所有命令,这意味着您无法控制执行顺序。


FYI,request()库及其对应的派生类已被弃用,将不再积极开发以添加新功能。列出了所有新项目中推荐的替代方案here。我最喜欢的是got(),它是从头开始构建以使用Promise的,但是您可以选择任何具有所需功能和/或所需API的人。

相关问题