如果我等待2个函数,我可以保证返回对象将具有两个值

时间:2017-03-27 08:28:01

标签: javascript async-await

我有以下代码

module.exports = async function (req, res) {
 const station1 = await getStation('one')
 const station2 = await getStation('two')

 return { stations: [station1, station2] }
}

我可以保证在发送最终返回值时它肯定会同时包含station1station2数据,或者我是否需要将函数调用包装在{{1}中}

3 个答案:

答案 0 :(得分:6)

正如您所知,只有当两个return承诺得到解决时才能保证getStation()语句才会被执行。

然而,第二次调用getStation只会在第一个承诺解决后才会发生,使它们串行运行。由于它们之间没有依赖关系,因此如果要并行运行它们,就可以获得性能。

尽管可以使用Promise.all实现这一点,但您可以通过首先检索这两个承诺,然后再对它们执行await来实现相同的目标:

module.exports = async function (req, res) {
    const promise1 = getStation('one');
    const promise2 = getStation('two');
    return { stations: [await promise1, await promise2] }
}

现在两个电话都将在"同一个"时间,只有return语句将等待两个承诺解决。这也在MDN's "simple example"中说明。

答案 1 :(得分:1)

await关键字实际上让你在代码行上“等待”,同时运行异步操作。

这意味着在解决异步操作之前,您不会继续执行下一行代码。如果您的代码与结果存在依赖关系,那么这很好。

示例:

const res1 = await doSomething();
if(res1.isValid)
{
   console.log('do something with res1 result');
}

以下代码示例将等待三秒后解析的promise。检查日期打印到控制台以了解等待做什么:

async function f1() {
  console.log(new Date());

  // Resolve after three seconds
  var p = new Promise(resolve => {
    setTimeout(() => resolve({}),3000);
  });

  await p;

  console.log(new Date());
}

f1();

ES6Console

BTW,在您的情况下,由于您不使用station1的结果,因此最好使用Promise.all并行工作。

检查此示例(它将按照您上面编码的方式运行3秒而不是4秒):

async function f1() {
  console.log(new Date());

  // Resolve after three seconds
  var p1 = new Promise(resolve => {
    setTimeout(() => resolve({a:1}),3000);
  });

  // Resolve after one second
  var p2 = new Promise(resolve => {
    setTimeout(() => resolve({a:2}),1000);
  });

  // Run them parallel - Max(three seconds, one second) -> three seconds.
  var res = await Promise.all([p1,p2]);

  console.log(new Date());

  console.log('result:' + res);
}

f1();

ES6Console

答案 2 :(得分:1)

如果await getStation('one')await getStation('two')中的任何一个失败,将从异步函数抛出异常。因此,您应始终从两个承诺中获得已解决的值。

您可以按如下方式重写您的功能,以使用Promise.all

module.exports = async function (req, res) {
 try{

     const [station1, station2] = await Promise.all([
      getStation('one'),
      getStation('two')
     ]);

     return { stations: [station1, station2] };

  } catch (e) {
      throw e;
  }
}