async/await 如何串行和并行工作?
How is async/await working in serial and parallel?
我有两个 async
函数。他们都在等待两个 3 秒的函数调用。但是第二个比第一个快。我认为更快的是 运行 并行和其他串行。我的假设正确吗?如果是,为什么会发生这种情况,因为这两个函数在逻辑上看起来是一样的?
function sleep() {
return new Promise(resolve => {
setTimeout(resolve, 3000);
});
}
async function serial() {
await sleep();
await sleep();
}
async function parallel() {
var a = sleep();
var b = sleep();
await a;
await b;
}
serial().then(() => {
console.log("6 seconds over");
});
parallel().then(() => {
console.log("3 seconds over");
});
如果你这样写你的 serial
函数会更清楚:
async function serial() {
var a = sleep(); //
await a; // await sleep();
var b = sleep(); //
await b; // await sleep();
}
async function parallel() {
var a = sleep();
var b = sleep();
await a;
await b;
}
这里可以清楚的看到,在serial
函数中,第二个sleep()
是在第一个sleep()
完成后才调用的,而在parallel
中是调用立即,在第一个完成之前,然后等待两个完成。因此,虽然它们可能看起来在功能上相同,但它们有细微的不同。
因为sleep()
函数是一个同步函数,它只是return一个异步promise,例如:
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
在parallel()
中,两个sleep()
同步初始化两个promise,同时等待resolved,大约需要3s。
但是,在serial()
中,两个await sleep()
意味着第二个sleep()
promise必须等待第一个sleep()
被解决,所以它会是大约6s。
Frxstream 已经有 。在此基础上,提供一些观点:
首先要认识到的是创建了 Promise "hot" - 也就是说,当您拥有一个 Promise 对象时,它已经 "in progress".
第二个重要的概念是 await
就像一个 "asynchronous wait" - 也就是说,它会暂停函数的执行,直到该承诺完成。
因此,serial
函数调用 sleep
,返回承诺,然后(异步)等待该承诺完成。在该承诺 3 秒后完成后,serial
再次调用 sleep
,得到一个承诺,然后(异步)等待该承诺完成。 3 秒后该承诺完成后,serial
完成。
parallel
函数调用 sleep
并将其 promise 存储在 a
,然后调用 sleep
并将其 promise 存储在 b
,然后(异步)等待 a
完成。 a
3 秒后完成后,parallel
(异步)等待 b
完成。 b
几乎立即完成后,parallel
完成。
连载运行:运行函数一个接一个
// It’s slow! and use only for serial(one after another) run
async function doThings() {
const thing1 = await asyncThing1(); // waits until resolved/rejected
console.log(thing1);
const thing2 = await asyncThing2(); // starts only after asyncThing1() has finished.
console.log(thing2);
}
doThings();
并行运行: 运行函数并行
// ✅ async code is run in parallel!
async function doThings() {
const p1 = asyncThing1(); // runs parallel
const p2 = asyncThing2(); // runs parallel
// Method 1: Prefer => Promise.all()
const [resultThing1, resultThing2] = await Promise.all([p1, p2]); // waits for all
// the promises get resolved or fails fast (If one of the promises supplied to it
// rejects, then the entire thing rejects).
// Method 2: Not-Preferred
const resultThing1 = await p1;
const resultThing2 = await p2;
console.log(resultThing1); // reaches here only after both the p1 & p2 have completed.
console.log(resultThing2);
}
doThings();
我有两个 async
函数。他们都在等待两个 3 秒的函数调用。但是第二个比第一个快。我认为更快的是 运行 并行和其他串行。我的假设正确吗?如果是,为什么会发生这种情况,因为这两个函数在逻辑上看起来是一样的?
function sleep() {
return new Promise(resolve => {
setTimeout(resolve, 3000);
});
}
async function serial() {
await sleep();
await sleep();
}
async function parallel() {
var a = sleep();
var b = sleep();
await a;
await b;
}
serial().then(() => {
console.log("6 seconds over");
});
parallel().then(() => {
console.log("3 seconds over");
});
如果你这样写你的 serial
函数会更清楚:
async function serial() {
var a = sleep(); //
await a; // await sleep();
var b = sleep(); //
await b; // await sleep();
}
async function parallel() {
var a = sleep();
var b = sleep();
await a;
await b;
}
这里可以清楚的看到,在serial
函数中,第二个sleep()
是在第一个sleep()
完成后才调用的,而在parallel
中是调用立即,在第一个完成之前,然后等待两个完成。因此,虽然它们可能看起来在功能上相同,但它们有细微的不同。
因为sleep()
函数是一个同步函数,它只是return一个异步promise,例如:
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
在parallel()
中,两个sleep()
同步初始化两个promise,同时等待resolved,大约需要3s。
但是,在serial()
中,两个await sleep()
意味着第二个sleep()
promise必须等待第一个sleep()
被解决,所以它会是大约6s。
Frxstream 已经有
首先要认识到的是创建了 Promise "hot" - 也就是说,当您拥有一个 Promise 对象时,它已经 "in progress".
第二个重要的概念是 await
就像一个 "asynchronous wait" - 也就是说,它会暂停函数的执行,直到该承诺完成。
因此,serial
函数调用 sleep
,返回承诺,然后(异步)等待该承诺完成。在该承诺 3 秒后完成后,serial
再次调用 sleep
,得到一个承诺,然后(异步)等待该承诺完成。 3 秒后该承诺完成后,serial
完成。
parallel
函数调用 sleep
并将其 promise 存储在 a
,然后调用 sleep
并将其 promise 存储在 b
,然后(异步)等待 a
完成。 a
3 秒后完成后,parallel
(异步)等待 b
完成。 b
几乎立即完成后,parallel
完成。
连载运行:运行函数一个接一个
// It’s slow! and use only for serial(one after another) run
async function doThings() {
const thing1 = await asyncThing1(); // waits until resolved/rejected
console.log(thing1);
const thing2 = await asyncThing2(); // starts only after asyncThing1() has finished.
console.log(thing2);
}
doThings();
并行运行: 运行函数并行
// ✅ async code is run in parallel!
async function doThings() {
const p1 = asyncThing1(); // runs parallel
const p2 = asyncThing2(); // runs parallel
// Method 1: Prefer => Promise.all()
const [resultThing1, resultThing2] = await Promise.all([p1, p2]); // waits for all
// the promises get resolved or fails fast (If one of the promises supplied to it
// rejects, then the entire thing rejects).
// Method 2: Not-Preferred
const resultThing1 = await p1;
const resultThing2 = await p2;
console.log(resultThing1); // reaches here only after both the p1 & p2 have completed.
console.log(resultThing2);
}
doThings();