Promise.all (). Sonra () çözülsün mü?


96

Düğüm 4.x'i kullanma. Elinizde bir Promise.all(promises).then()veriyi çözmenin ve bir sonrakine aktarmanın doğru yolu .then()nedir?

Bunun gibi bir şey yapmak istiyorum:

Promise.all(promises).then(function(data){
  // Do something with the data here
}).then(function(data){
  // Do more stuff here
});

Ancak verileri 2. kata nasıl alacağımdan emin değilim .then(). Ben kullanamaz resolve(...)ilk .then(). Bunu yapabileceğimi anladım:

return Promise.all(promises).then(function(data){
  // Do something with the data here
  return data;
}).then(function(data){
  // Do more stuff here
});

Ama bunu yapmanın doğru yolu bu gibi görünmüyor ... Buna doğru yaklaşım nedir?

Yanıtlar:


143

Ama bunu yapmanın doğru yolu bu değil gibi görünüyor ..

Bu gerçekten (ya da en azından bunu yapmak için uygun bir yoldur bir bunu yapmak için uygun bir yol). Bu, vaatlerin önemli bir yönüdür, bunlar bir ardışık düzen ve veriler, ardışık düzenteki çeşitli işleyiciler tarafından masaj yapılabilir.

Misal:

const promises = [
  new Promise(resolve => setTimeout(resolve, 0, 1)),
  new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
  .then(data => {
    console.log("First handler", data);
    return data.map(entry => entry * 10);
  })
  .then(data => {
    console.log("Second handler", data);
  });

( catchişleyici kısalık nedeniyle ihmal edildi. Üretim kodunda, her zaman ya sözü iletin ya da reddi ele alın.)

Buradan gördüğümüz çıktı:

İlk işleyici [1,2]
İkinci işleyici [10,20]

... çünkü ilk işleyici iki vaatin ( 1ve 2) çözümünü bir dizi olarak alır ve sonra her biri 10 ile çarpılan yeni bir dizi oluşturur ve onu döndürür. İkinci işleyici, ilk işleyicinin döndürdüğünü alır.

Yaptığınız ek iş senkron ise, ayrıca koyabilirsiniz içinde ilk işleyicisi:

Misal:

const promises = [
  new Promise(resolve => setTimeout(resolve, 0, 1)),
  new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
  .then(data => {
    console.log("Initial data", data);
    data = data.map(entry => entry * 10);
    console.log("Updated data", data);
    return data;
  });

... ancak eşzamansızsa, iç içe geçeceği için bunu yapmak istemezsiniz ve yuvalama hızla kontrolden çıkabilir.


1
İlginç. Teşekkür ederim. Öyleyse, rejectilk Promiseişlevden sonra bir değer elde etmek mümkün değil mi? Ya da zincirin herhangi bir yerinde bir hata atmak sizi .catch()? Eğer durum buysa, rejectilk etapta ne anlamı var ? Neden sadece hata atmıyorsun? Tekrar teşekkürler,
Jake Wilson

6
@JakeWilson: Bunlar farklı sorular. Ama iki ayrı şeyler karıştırıyorsun: Oluşturma ve söz yerleşme ve taşıma vaadi. Sözü oluştururken ve yerine getirirken, resolveve kullanırsınız reject. Eğer bittiğinde işleme , işlem başarısız olursa, sen gerçekten de başarısızlık yolunu tetiklemek için bir istisna yoktur. Ve evet, orijinal Promisegeri aramadan bir istisna da atabilirsiniz (kullanmak yerine reject), ancak tüm hatalar istisna değildir.
TJ Crowder


1

Bugün NodeJS yeni async/awaitsözdizimini desteklemektedir . Bu kolay bir sözdizimidir ve hayatı çok daha kolaylaştırır

async function process(promises) { // must be an async function
    let x = await Promise.all(promises);  // now x will be an array
    x = x.map( tmp => tmp * 10);              // proccessing the data.
}

const promises = [
   new Promise(resolve => setTimeout(resolve, 0, 1)),
   new Promise(resolve => setTimeout(resolve, 0, 2))
];

process(promises)

Daha fazla bilgi edin:


1
Süreçten her bir söze parametreleri nasıl aktarabilirim? @ Aminadav Glickshtein
bhaRATh
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.