首页 > 解决方案 > 为什么要将 Promise 对象存储在变量中?

问题描述

假设我们有一个函数可以解析如下的 Promise:

function timeoutPromise(interval) {
  return new Promise((resolve, reject) => {
    setTimeout(function(){
      resolve("done");
    }, interval);
  });
};

让我们假设我们以两种不同的方式在异步函数中调用该函数;

慢同步方式:

async function timeTest() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}

在这里,我们直接等待所有三个 timeoutPromise() 调用。随后的每一个都被迫等到最后一个完成,这将导致总运行时间约为 9 秒。

和快速的异步方式

async function timeTest() {
  const timeoutPromise1 = timeoutPromise(3000);
  const timeoutPromise2 = timeoutPromise(3000);
  const timeoutPromise3 = timeoutPromise(3000);

  await timeoutPromise1;
  await timeoutPromise2;
  await timeoutPromise3;
}

在这里,我们将三个 Promise 对象存储在变量中,这具有触发它们关联的进程都同时运行的效果。这将导致总运行时间约为 3 秒。

但问题是,为什么将 Promise 对象存储在变量中会导致它们的关联进程同时运行?引擎盖下会发生什么?

标签: javascript

解决方案


await foo();
await bar();

只会在返回的承诺被解决bar调用(并因此创建第二个承诺) 。foo

var x = foo();
var y = bar();
await x;

在返回的承诺被解决之前调用bar(并因此创建第二个承诺) 。foo

这就是使承诺“并发”的原因。如果你console.log在不同的地方添加,你会看到执行的不同:

function timeoutPromise(name, interval) {
  return new Promise((resolve, reject) => {
    console.log(`Promise ${name} created.`);
    setTimeout(function(){
      console.log(`Promise ${name} resolved.`);
      resolve("done");
    }, interval);
  });
};

async function timeTest1() {
  console.log('test 1');
  await timeoutPromise(1, 3000);
  console.log('between promise 1 and 2');
  await timeoutPromise(2, 3000);
}

async function timeTest2() {
  console.log('test 2');
  const timeoutPromise1 = timeoutPromise(1, 3000);
  console.log('between promise 1 and 2');
  const timeoutPromise2 = timeoutPromise(2, 3000);

  await timeoutPromise1;
  console.log('between promise 1 and 2 with await');
  await timeoutPromise2;
}

timeTest1().then(timeTest2);


推荐阅读