从async / await并发开始

时间:2018-07-30 12:18:41

标签: javascript asynchronous async-await

我以为我对异步等待有了很好的了解,直到尝试了这一点:

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('what'), 10000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('?'), 15000);
});

async function asyncTest() {
  console.time();
  const p1 = await promise1;

  if (p1 === 'what') {
    var p2 = await promise2;
  }

  console.log(p1, p2);
  console.timeEnd();
}

asyncTest()

15000毫秒后,asyncTest正在记录p1p2。如果将promise1promise2转换为返回这些承诺的函数,则执行时间为25000毫秒。我不知道是怎么回事。有人可以解释吗?

3 个答案:

答案 0 :(得分:2)

问题在于,您在声明无条件回调后会立即对其进行调用。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('what'), 10000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('?'), 15000);
});

这时,两个回调都已被调用。从这一点起10000毫秒,promise1将解决。从这一点开始15000毫秒,promise2将解决。

async function asyncTest() {
  console.time();
  const p1 = await promise1;

  if (p1 === 'what') {
    var p2 = await promise2;
  }

  console.log(p1, p2);
  console.timeEnd();
}

asyncTest()

此时,由于两个回调都已被调用,因此将在15000毫秒内解决这两个回调,这是您观察到的。

为了将其扩展到您期望的25000ms,请尝试按以下方式重写Promises:

const promise1 = () => new Promise((resolve, reject) => {
  setTimeout(() => resolve('what'), 10000);
});

const promise2 = () => new Promise((resolve, reject) => {
  setTimeout(() => resolve('?'), 15000);
});

请注意,这些现在是不会立即被调用的函数表达式。然后重写您的asyncTest函数来调用这些表达式,而不是仅仅等待已经执行的Promises:

async function asyncTest() {
  console.time();
  const p1 = await promise1();

  if (p1 === 'what') {
    var p2 = await promise2();
  }

  console.log(p1, p2);
  console.timeEnd();
}

这将强制promise2等到promise1完成后再开始执行。

答案 1 :(得分:1)

代码处于当前状态:

您运行setTimeout并将一个应处理结果的承诺分配给promise1。之后,您立即对promise2做同样的事情。

因此,promise2在promise1之后约五秒钟解决。


如果您更改代码以使promise1promise2为函数,则:

您运行setTimeout返回一个将处理结果的承诺给await。它将等到承诺在10秒后解决。然后它将结果分配给p1

然后(即,经过10秒而不是立即过去),它将对p2执行相同的操作。


简而言之:

在第一个示例中,在设置promise2进行之前,您不必等待promise1。

描述了所做的更改后,在设置promise2进行之前,先执行await promise1。

答案 2 :(得分:1)

在第一个示例中,两个诺言在开始时即刻触发,并且当浏览器执行行var p2 = await promise2;时,诺言2是半解析的方式,await语句会暂停5000毫秒。

console.log('promise1 created');
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('what'), 10000);
});

console.log('promise2 created');
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('?'), 15000);
});

async function asyncTest() {
  console.time();
  const p1 = await promise1;

  if (p1 === 'what') {
    var p2 = await promise2;
  }

  console.log(p1, p2);
  console.timeEnd();
}

asyncTest();

在第二个示例中,仅当浏览器到达调用功能触发承诺的行时,才触发承诺。因此,在第var p2 = await promise2();行创建了第二个承诺,并且await语句暂停了15000 ms。因此,总执行时间为25000 ms。

const promise1 = () => {
  console.log('promise1 created');
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve('what'), 10000);
  })
};


const promise2 = () => {
  console.log('promise2 created');
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve('?'), 15000);
  })
};

async function asyncTest() {
  console.time();
  const p1 = await promise1();

  if (p1 === 'what') {
    var p2 = await promise2();
  }

  console.log(p1, p2);
  console.timeEnd();
}

asyncTest();