Promise.all() 和并行承诺在节点上有所不同

Mah*_*esh 3 node.js axios

我有一个场景,我可以实现我的代码以两种方式发出 axios 请求

第一种方式

const data = {};

try {

  if (searchArray.includes('address')) {
    const address = await axios('./getAddress')
    data.addresses = address.data;
  }

  if (searchArray.includes('email')) {
    const email = await axios('./email')
    data.emails = email.data;
  }

  if (searchArray.includes('phone')) {
    const phoneNumber = await axios('./phone')
    data.phoneNumbers = phoneNumber.data;

  }
} catch (err) {
  return res.status(constants.HTTP_SERVER_ERROR).json(err);
}

res.status(200).json(data);
Run Code Online (Sandbox Code Playgroud)

第二种方式

const data = {};
const promises = []

if (searchArray.includes('address')) {
  promises.push(axios('./getAddress'))
}

if (searchArray.includes('email')) {
  promises.push(axios('./email'))
}

if (searchArray.includes('phone')) {
  promises.push(axios('./phone'))
}

Promise.all(promises)
  .then(results => {
    res.status(200).json(results);
  })
  .catch(err) {
    return res.status(constants.HTTP_SERVER_ERROR).json(err);
  }
Run Code Online (Sandbox Code Playgroud)

哪种方法更好?为什么?

我更喜欢第一种方法,因为我可以拥有结构良好的数据而不是完整的结果数组。但是得到了顺序实施而不是并行实施的建议

我假设 node 是单线程的,所以在实现它时没有发现任何区别(如果我使用 async 和 await,我可能是错的)

dou*_*arp 6

第二种方法会更高效。

在第一个示例中,假设每个请求需要 1 秒才能返回,因此在等待一个请求的结果后再进行下一个请求时,至少需要 3 秒以上的时间来返回结果。

在第二种方法中,您一次发出所有请求,然后等待 IO 回调。处理完所有请求后,Promise.all()将解决。如果每个请求需要大约 1 秒但并行发出,则您的响应也将大约为 1 秒。

我会使用如下语法来保持可读性,因为您似乎正在使用async/await并且不需要引用promises.

try {
  const [addresses, emails, phones] = await Promise.all([
    searchArray.includes('address') 
      ? axios('./getAddress') : Promise.resolve({}),
    searchArray.includes('email') 
      ? axios('./email') : Promise.resolve({}),
    searchArray.includes('phone') 
      ? axios('./phone') : Promise.resolve({}),
  ]);
  return res.status(200).json({
     addresses: addresses.data,
     emails: emails.data,
     phoneNumbers: phones.data,
  });
} catch (err) {
  return res.status(constants.HTTP_SERVER_ERROR).json(err);
}
Run Code Online (Sandbox Code Playgroud)


bin*_*dMe 5

“Javascript 是单线程的”这句话常常让人们感到困惑。

虽然代码执行的主线程是单线程的,但异步执行通常不由主线程处理。因此,基本上,当您串行执行少量异步任务而不是并行执行任务时,并行执行肯定会更快。

如果我们需要将许多依赖的异步操作包装在一个承诺中,有时我们会采用异步等待方法。独立的异步操作应该并行执行。