forEach/map ve async el ele gitmez

Zaman zaman, zaman uyumsuz işlevleri forEach ve map işlevleriyle geçirme eğilimindeyiz.
örneğin:
[1,2,3,4,5].forEach(async (n) => setTimeout(console.log(n), 1000));
Sonuç: 1..5'ten itibaren tüm sayılar arka arkaya yazdırılır ancak her satır yazdırıldıktan sonra 1 saniye boşluk kalmaz .
Bu neden oluyor?
Şu javascipt işlevine bakın:
async function doubleOf(n) {
return n*2;
}
Sonuç: Bu aslında bir sayıya çözümlenen bir Promise döndürüyor.
Bu fonksiyonun bir TypeScript eşdeğerini katı tiplerle yazarsak, bu işleri netleştirecektir.
Aşağıdaki kod derlenmeyecek :
async function doubleOf(n: number): number {
return n*2;
}
Doğru sürüm şöyle olacaktır:
async function doubleOf(n: number): Promise<number> {
return n*2;
}
async-await tarafından sağlanan sözdizimsel şekere aldanmayın. Async kullanmadan saf vaatler yazsaydık, yukarıdaki işlev şöyle görünürdü:
function doubleOf(n) {
return new Promise((resolve) => resolve(n*2));
}
function doubleOf(n: number): Promise<number> {
return new Promise((resolve) => resolve(n*2));
}

doubleOf
Bir sayı alan ve bir sayı döndüren bir fonksiyonumuz var . Düz eski javascript.doubleOfOldWay
Bir sayı alan ve bir sayıya çözümlenen bir söz veren bir işlevimiz var .doubleOfNewWay
Bir sayıyı alan ve bir sayı döndürüyormuş gibi görünen, ancak aslında tıpkıdoubleOfOldWay
işlev gibi bir sayıya çözümlenen bir söz veren bir zaman uyumsuz işlevimiz var .doubleOfOldWay
vedoubleOfNewWay
fonksiyonlar tamamen aynıdır.doubleOfOldWay
Ve bu nedenle, ve işlevleri tarafından döndürülen değerler üzerinde bir çarpma işlemi yürütmeye çalıştığımızda , birden çok söz veremeyeceğimiz için (tabii ki!)doubleOfNewWay
sonuç oldu .NaN
- çarpmak için
doubleOfOldWay
vedoubleOfNewWay
:
İlk örneğimize geri dönelim:
[1,2,3,4,5].forEach(async (n) => setTimeout(console.log(n), 1000));
Bu forEach işlevinden beklediğimizi uygulamanın en doğru yolu basit bir for döngüsü kullanmaktır:
for(const number of [1,2,3,4,5]) {
console.log(number);
await new Promise(resolve => setTimeout(resolve, 1000)); // Sleep for "atleast" 1 second
}
[1,2,3,4,5].map(async (n) => n*2);
(5) [Promise, Promise, Promise, Promise, Promise]
0: Promise {<fulfilled>: 2}
1: Promise {<fulfilled>: 4}
2: Promise {<fulfilled>: 6}
3: Promise {<fulfilled>: 8}
4: Promise {<fulfilled>: 10}
Her sayının iki katının bir listesini almak için yapabileceklerimiz:
await Promise.all([1,2,3,4,5].map(async (n) => n*2));
[2, 4, 6, 8, 10]