javascript - Istovremeni početak s async/await
Mislio sam da imam prilično dobro razumijevanje async await dok ovo nisam pokušao:
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()Nakon 15000 ms, asyncTest zapisuje p1 i p2. Ako se umjesto toga promise1 i promise2 pretvore u funkcije koje vraćaju te promise-ove, vrijeme izvršenja je tada 25000 ms. Nemam pojma što se događa. Može li netko objasniti ovo?
Odgovor #1
Problem je u tome što se vaši Promise pozivi vraćaju odmah nakon što ih deklarirate.
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('what'), 10000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve('?'), 15000);
});
U ovom trenutku obje povratne funkcije su pozvane. 10000 ms od ovog trenutka, promise1 će biti riješen. 15000 ms od ovog trenutka, promise2 će biti riješen.
async function asyncTest() {
console.time();
const p1 = await promise1;
if (p1 === 'what') {
var p2 = await promise2;
}
console.log(p1, p2);
console.timeEnd();
}
asyncTest()
U ovom trenutku, budući da su oba povratna poziva već pozvana, oba će biti riješena unutar 15000 ms, što ste i primijetili.
Kako biste ovo produžili na 25000 ms koje ste očekivali, pokušajte prepisati Promises na sljedeći način:
const promise1 = () => new Promise((resolve, reject) => {
setTimeout(() => resolve('what'), 10000);
});
const promise2 = () => new Promise((resolve, reject) => {
setTimeout(() => resolve('?'), 15000);
});
Napomena, ovo su sada funkcijske izraze koje neće biti odmah pozvane. Zatim prepišite svoju asyncTest funkciju kako bi pozivala ove izraze umjesto da jednostavno čeka već izvršavajuće Promise:
async function asyncTest() {
console.time();
const p1 = await promise1();
if (p1 === 'what') {
var p2 = await promise2();
}
console.log(p1, p2);
console.timeEnd();
}
Ovo će prisiliti promise2 da čeka dok promise1 ne bude dovršen prije nego što započne izvršavanje.
Odgovor #2
S kodom u njegovom trenutnom stanju:
Pokrenete setTimeout i dodijelite obećanje koje će obraditi njegov rezultat u promise1. Neposredno nakon toga, učinite isto za promise2.
Dakle, promise2 se rješava otprilike pet sekundi nakon promise1.
Ako promijenite kod tako da su promise1 i promise2 funkcije, tada:
Pokrenete setTimeout koji vraća obećanje koje će svoje rezultate obraditi u await. Čekat će dok se obećanje ne riješi 10 sekundi kasnije. Zatim će dodijeliti rezultat u p1.
Zatim (tj. nakon što prođe 10 sekundi umjesto odmah) učinit će isto za p2.
Ukratko:
U prvom primjeru, ne čekate promise1 prije nego što pokrenete promise2.
Nakon što napravite promjenu koju opisujete, radite await na promise1 prije nego što postavite da promise2 krene.
