Singkatnya, pesanan dipertahankan .
Mengikuti spec yang Anda tautkan, Promise.all(iterable)
mengambil iterable
(yaitu, objek yang mendukung Iterator
antarmuka) sebagai parameter dan kemudian pada panggilan PerformPromiseAll( iterator, constructor, resultCapability)
dengan itu, di mana yang terakhir loop iterable
menggunakan IteratorStep(iterator)
.
Ini berarti bahwa jika iterable yang Anda lewati Promise.all()
diperintahkan secara ketat, mereka akan tetap diperintahkan begitu dilewati.
Penyelesaian diimplementasikan melalui Promise.all() Resolve
tempat setiap janji yang diselesaikan memiliki [[Index]]
slot internal , yang menandai indeks janji di input asli.
Semua ini berarti bahwa output secara ketat dipesan sebagai input selama input benar-benar dipesan (misalnya, sebuah array).
Anda dapat melihat ini beraksi di biola di bawah ini (ES6):
// Used to display results
const write = msg => {
document.body.appendChild(document.createElement('div')).innerHTML = msg;
};
// Different speed async operations
const slow = new Promise(resolve => {
setTimeout(resolve, 200, 'slow');
});
const instant = 'instant';
const quick = new Promise(resolve => {
setTimeout(resolve, 50, 'quick');
});
// The order is preserved regardless of what resolved first
Promise.all([slow, instant, quick]).then(responses => {
responses.map(response => write(response));
});
throw
menjadi pengecualian jika Anda meneruskannya kePromise.all
. Selain itu, saya tidak mengetahui adanya implementasi janji pengguna lahan yang saat ini mendukung kelulusan iterables meskipun banyak yang memperdebatkannya dan memutuskan untuk tidak melakukannya pada saat itu.Promise.all
tidak bisa digunakan untuk menjalankan berbagai janji secara berurutan, satu demi satu. Janji-janji yang dimuat ke dalam iterator harus independen satu sama lain agar ini dapat diprediksi.Seperti jawaban sebelumnya telah menyatakan,
Promise.all
menggabungkan semua nilai yang diselesaikan dengan array yang sesuai dengan urutan input dari Janji asli (lihat Janji Agregat ).Namun, saya ingin menunjukkan, bahwa pesanan hanya dipertahankan di sisi klien!
Bagi pengembang sepertinya Janji itu dipenuhi secara berurutan, tetapi dalam kenyataannya, Janji tersebut diproses dengan kecepatan yang berbeda. Ini penting untuk diketahui ketika Anda bekerja dengan backend jarak jauh karena backend mungkin menerima Janji Anda dalam urutan yang berbeda.
Berikut adalah contoh yang menunjukkan masalah dengan menggunakan batas waktu:
Janji
Dalam kode yang ditunjukkan di atas, tiga Janji (A, B, C) diberikan kepada
Promise.all
. Tiga Janji dijalankan dengan kecepatan yang berbeda (C menjadi yang tercepat dan B menjadi yang paling lambat). Itu sebabnyaconsole.log
pernyataan Janji muncul dalam urutan ini:Jika Janji adalah panggilan AJAX, maka backend jarak jauh akan menerima nilai-nilai ini dalam urutan ini. Tetapi di sisi klien
Promise.all
memastikan bahwa hasilnya dipesan sesuai dengan posisi aslimyPromises
array. Itu sebabnya hasil akhirnya adalah:Jika Anda ingin menjamin juga pelaksanaan aktual Janji Anda, maka Anda akan memerlukan konsep seperti antrian Janji. Berikut ini adalah contoh menggunakan p-antrian (hati-hati, Anda harus membungkus semua Janji dalam fungsi):
Antrian Janji Berurutan
Hasil
sumber
Ya, nilai dalam
results
berada dalam urutan yang sama denganpromises
.Orang mungkin mengutip spec ES6 pada
Promise.all
, meskipun itu agak berbelit-belit karena api iterator yang digunakan dan konstruktor janji generik. Namun, Anda akan melihat bahwa setiap callback resolver memiliki[[index]]
atribut yang dibuat dalam iterasi janji-array dan digunakan untuk mengatur nilai pada array hasil.sumber