javascript - async/await ile eşzamanlı başlatma


Async await konusunu oldukça iyi anladığımı düşünmüştüm, ta ki bunu deneyene kadar:

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()

15000ms sonra, asyncTest p1 ve p2'yi logluyor. Eğer bunun yerine promise1 ve promise2 bu promiseleri döndüren fonksiyonlara dönüştürülürse, yürütme süresi 25000ms oluyor. Ne olduğunu gerçekten anlamıyorum. Bunu açıklamak isteyen var mı?

Cevap #1

Sorun, Promise geri çağırmalarınızın onları tanımladıktan hemen sonra çağrılmasıdır.

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

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

Bu noktada, her iki geri arama da çağrılmıştır. Bu noktadan 10000ms sonra, promise1 çözümlenecek. Bu noktadan 15000ms sonra, promise2 çözümlenecek.

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

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

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

asyncTest()

Bu noktada, her iki geri arama zaten çağrıldığı için, her ikisi de 15000ms içinde çözülecek, bu da sizin gözlemlediğiniz durumdur.

Bunu beklediğiniz 25000ms'ye uzatmak için, Promiseleri şu şekilde yeniden yazmayı deneyin:

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

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

Bunların artık hemen çağrılmayacak olan fonksiyon ifadeleri olduğunu unutmayın. Daha sonra asyncTest fonksiyonunuzu, halihazırda çalışan Promise'leri beklemek yerine bu ifadeleri çağıracak şekilde yeniden yazın:

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

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

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

Bu, promise2'nin yürütmeye başlamadan önce promise1'in tamamlanmasını beklemesini zorlayacaktır.

Cevap #2

Kodun mevcut durumu ile:

setTimeout çalıştırırsınız ve sonucunu işleyecek bir promise'i promise1'e atarsınız. Hemen ardından, promise2 için aynı şeyi yaparsınız.

Yani promise2, promise1'den yaklaşık beş saniye sonra çözülür.

Eğer kodu promise1 ve promise2 fonksiyonlar olacak şekilde değiştirirseniz, o zaman:

setTimeout çalıştırırsınız, bu bir sonucu await ile işleyebilecek bir promise döndürecektir. Promise 10 saniye sonra çözülene kadar bekleyecektir. Sonra sonucu p1'e atayacaktır.

O zaman (yani hemen yerine 10 saniye geçtikten sonra) aynı şeyi p2 için yapacaktır.

Kısaca:

İlk örnekte, promise2'yi başlatmadan önce promise1'in tamamlanmasını beklemiyorsunuz.

Açıkladığınız değişikliği yaptıktan sonra, promise2'yi başlatmadan önce await promise1 yaparsınız.