Diberikan kode berikut:
var arr = [1,2,3,4,5];
var results: number[] = await arr.map(async (item): Promise<number> => {
await callAsynchronousOperation(item);
return item + 1;
});
yang menghasilkan kesalahan berikut:
TS2322: Ketik 'Janji <nomor> []' tidak dapat ditentukan untuk mengetik 'angka []'. Ketik 'Janji <nomor> tidak dapat ditentukan untuk mengetik' angka '.
Bagaimana saya bisa memperbaikinya? Bagaimana saya bisa membuat async await
dan Array.map
bekerja bersama?
arr.map()
sinkron dan tidak mengembalikan janji.map
, yang mengharapkan operasi sinkron, dan berharap itu berfungsi.async
, Anda membuat fungsi itu mengembalikan janji. Jadi tentu saja, peta async mengembalikan sejumlah janji :)Jawaban:
Masalahnya di sini adalah bahwa Anda mencoba
await
berbagai janji daripada janji. Ini tidak melakukan apa yang Anda harapkan.Ketika objek yang diteruskan
await
bukan Janji,await
cukup kembalikan nilai apa adanya segera daripada mencoba menyelesaikannya. Jadi sejak Anda melewatiawait
array (objek Promise) di sini alih-alih Janji, nilai yang dikembalikan dengan menunggu hanyalah array itu, yang bertipePromise<number>[]
.Apa yang perlu Anda lakukan di sini adalah memanggil
Promise.all
array yang dikembalikan olehmap
untuk mengubahnya menjadi Janji tunggal sebelumawait
ing itu.Menurut dokumen MDN untuk
Promise.all
:Jadi dalam kasus Anda:
Ini akan menyelesaikan kesalahan spesifik yang Anda temui di sini.
sumber
:
titik dua?callAsynchronousOperation(item);
dengan dan tanpaawait
di dalam fungsi peta async?await
fungsi akan menunggu operasi asinkron untuk menyelesaikan (atau gagal) sebelum melanjutkan, jika tidak maka akan segera dilanjutkan tanpa menunggu.Ada solusi lain untuk itu jika Anda tidak menggunakan Janji asli tetapi Bluebird.
Anda juga dapat mencoba menggunakan Promise.map () , mencampur array.map dan Promise.all
Jika Anda:
sumber
Promise.mapSeries
atau berurutanPromise.each
,Promise.map
memulai semuanya sekaligus.concurrency
opsi.Jika Anda memetakan ke array Janji, Anda kemudian dapat menyelesaikannya semua ke array angka. Lihat Janji . Semua.
sumber
Saya akan merekomendasikan menggunakan Promise.all seperti yang disebutkan di atas, tetapi jika Anda benar-benar ingin menghindari pendekatan itu, Anda dapat melakukan for atau loop lainnya:
sumber
Solusi di bawah ini untuk memproses semua elemen array secara tidak sinkron DAN mempertahankan pesanan:
Juga codepen .
Perhatikan kami hanya "menunggu" untuk Promise.all. Kami memanggil calc tanpa "menunggu" beberapa kali, dan kami segera mengumpulkan berbagai janji yang belum terselesaikan. Kemudian Promise.all menunggu resolusi semua dari mereka dan mengembalikan array dengan nilai yang diselesaikan secara berurutan.
sumber