首页 > 解决方案 > 在这种情况下我们应该使用 Promise.all 吗?内容细节

问题描述

在一个函数中,我们必须在进行处理和处理逻辑之前检查数据是否有效。需要检查数据库中是否存在数据,如果不存在,我会立即返回 404 错误并停止功能。但有些功能需要检查多于 1 个数据需要存在。

样本:

function async test(_idA, _idB, _idC) {
  const a = await findOneA({ _id: _idA });
  if (!a) {
    throw Error('A does not exists');
  }

  const b = await findOneB({ _id: _idB });
  if (!b) {
    throw Error('B does not exists');
  }

  const c = await findOneC({ _id: _idC });
  if (!c) {
    throw Error('C does not exists');
  }
}

或者

function async test(_idA, _idB, _idC) {
  const result = await Promise.all([
    findOneA({ _id: _idA }),
    findOneB({ _id: _idB }),
    findOneC({ _id: _idC }),
  ])
  const a = result[0];
  if (!a) {
    throw Error('A does not exists');
  }

  const b = result[1];
  if (!b) {
    throw Error('B does not exists');
  }

  const c = result[2];
  if (!c) {
    throw Error('C does not exists');
  }
}

我知道这两种方式都有实力,第一种如果a不存在则不需要3个查询,但是如果3个都存在,我们需要等待两者。但是第二个,我们使用 Promise.all,所以 3 个查询并行运行,所以速度更快,但我们总是必须同时查询 3 个查询。

那么哪种方式更好呢?

标签: node.js

解决方案


好的。您可以在代码中进行一些重构:

将异常移入“查找”功能

当您将异常移至 find 函数时,请确保该函数会返回某些内容,否则将引发异常。

您的代码将如下所示:

function async findOneA(param) {
  const result = ...
  ...
  if (!result)
    throw Error('A does not exists');

  return result;   
}

function async findOneB(param) {
  const result = ...
  ...
  if (!result)
    throw Error('B does not exists');

  return result;   
}

function async findOneC(param) {
  const result = ...
  ...
  if (!result)
    throw Error('C does not exists');

  return result;   
}

function async test(_idA, _idB, _idC) {
  const a = await findOneA({ _id: _idA });
  const b = await findOneB({ _id: _idB });
  const c = await findOneC({ _id: _idC });
}

使用 Promise.all

如果其中一个 Promise 拒绝,Promise all 将拒绝。现在你可以正常使用了

function async findOneA(param) {
  const result = ...
  ...
  if (!result)
    throw Error('A does not exists');

  return result;   
}

function async findOneB(param) {
  const result = ...
  ...
  if (!result)
    throw Error('B does not exists');

  return result;   
}

function async findOneC(param) {
  const result = ...
  ...
  if (!result)
    throw Error('C does not exists');

  return result;   
}

function async test(_idA, _idB, _idC) {
  const result = await Promise.all([
    findOneA({ _id: _idA }),
    findOneB({ _id: _idB }),
    findOneC({ _id: _idC })
  ])
  const a = result[0];
  const b = result[1];
  const c = result[2];
}

重构你的代码看起来更干净

现在你可以重构你的代码,让它看起来更干净一些。不那么冗长

function async findOneA(param) {
  const result = ...
  ...
  if (!result)
    throw Error('A does not exists');

  return result;   
}

function async findOneB(param) {
  const result = ...
  ...
  if (!result)
    throw Error('B does not exists');

  return result;   
}

function async findOneC(param) {
  const result = ...
  ...
  if (!result)
    throw Error('C does not exists');

  return result;   
}

function async test(_idA, _idB, _idC) {
  const [a, b, c] = await Promise.all([
    findOneA({ _id: _idA }),
    findOneB({ _id: _idB }),
    findOneC({ _id: _idC })
  ]);
}

推荐阅读