2015-06-01 10 views
8

Ich benutze babel, um meine [email protected] Code zu transpile und ich bin mit Versprechungen fest.Promise.allSettled in babel ES6-Implementierung

Ich brauche allSettled -Typ-Funktionalität, die ich in q und bluebird oder angular.$q zum Beispiel nutzen könnte.

Auf Babel's Core-Js Promise gibt es keine allSettled Methode.

Derzeit bin ich mit q.allSettled als Behelfslösung:

import { allSettled } from 'q';

Gibt es so etwas wie das in babel polyfill? Alternativ, was ist ein guter Algorithmus für mich zu versuchen zu implementieren?

Antwort

1

Alternativ, welche ist ein guter Algorithmus für mich zu versuchen zu implementieren?

  1. schafft ein neues Versprechen mit einem executor function
  2. verwenden, um einen Zähler/Ergebnis-Array in dem Rahmen des Exekutors
  3. Register, um einen dann() Callback mit jedem Versprechen Mutter der Ergebnisse in dem Array Spar
  4. Auflösungs-/ablehnen Versprechen aus Schritt 1, wenn der Zähler zeigt an, dass alle Eltern verspricht
+0

Schön, obwohl für jetzt werde ich bei der Verwendung von Q bleiben (was wahrscheinlich das gleiche tut). – Zlatko

+0

In Bezug auf Ihren Schritt 4, wie würde ich jemals wissen, das neue Versprechen abzulehnen? –

+0

@torazaburo du hast Recht, du würdest es niemals ablehnen, das ist der Punkt von allSettled :) Vielleicht ein Timeout, aber das ist ein anderer Anwendungsfall und nicht widerspiegeln, was q.allSettled tut. – Zlatko

1

Hier ist mein Versuch, etwas ähnliches, ich hav getan werden e Newsletter Service und in meinem Fall wollte ich mein allSettled Versprechen mit einer Reihe von allen Ergebnissen (Ablehnungen und Auflösungen), IN ORDER, wenn alle e-Mail-Versprechen abgerechnet wurden (alle E-Mails ausgegangen):

Newsletter.prototype.allSettled = function(email_promises) { 
    var allSettledPromise = new Promise(function(resolve, reject) { 
     // Keep Count 
     var counter = email_promises.length; 

     // Keep Individual Results in Order 
     var settlements = []; 
     settlements[counter - 1] = undefined; 

     function checkResolve() { 
      counter--; 
      if (counter == 0) { 
       resolve(settlements); 
      } 
     } 

     function recordResolution(index, data) { 
      settlements[index] = { 
       success: true, 
       data: data 
      }; 
      checkResolve(); 
     } 

     function recordRejection(index, error) { 
      settlements[index] = { 
       success: false, 
       error: error 
      }; 
      checkResolve(); 
     } 

     // Attach to all promises in array 
     email_promises.forEach(function(email_promise, index) { 
      email_promise.then(recordResolution.bind(null, index)) 
       .catch(recordRejection.bind(null, index)); 
     }); 
    }); 
    return allSettledPromise; 
} 
0

hier ist eine andere nehmen bei gleicher Funktionalität: spex.batch

die source code wäre zu viel hier re-post, also hier nur ein Beispiel aus dem batch processing, wie es zu benutzen:

var spex = require('spex')(Promise); 

// function that returns a promise; 
function getWord() { 
    return Promise.resolve("World"); 
} 

// function that returns a value; 
function getExcl() { 
    return '!'; 
} 

// function that returns another function; 
function nested() { 
    return getExcl; 
} 

var values = [ 
    123, 
    "Hello", 
    getWord, 
    Promise.resolve(nested) 
]; 

spex.batch(values) 
    .then(function (data) { 
     console.log("DATA:", data); 
    }, function (reason) { 
     console.log("REASON:", reason); 
    }); 

Diese Ausgänge:

DATA: [ 123, 'Hello', 'World', '!' ] 

Nun wollen wir es durch Ändern getWord dazu nicht machen:

function getWord() { 
    return Promise.reject("World"); 
} 

Jetzt ist die Ausgabe:

REASON: [ { success: true, result: 123 }, 
    { success: true, result: 'Hello' }, 
    { success: false, result: 'World' }, 
    { success: true, result: '!' } ] 

dh das gesamte Array angesiedelt ist, Reporting indexgebundene Ergebnisse.

Und wenn statt den gesamten Grund berichten wir getErrors() nennen:

console.log("REASON:", reason.getErrors()); 

dann wird der Ausgang sein:

REASON: [ 'World' ] 

Dieses nur einen schnellen Zugriff auf die Liste der Fehler zu vereinfachen ist, die aufgetreten .

12

Wenn Sie einen Blick auf die implementation of q.allSettled werfen, werden Sie sehen, es ist eigentlich ziemlich einfach zu implementieren. Hier ist, wie Sie es mit ES6 Promises implementieren können:

function allSettled(promises) { 
    let wrappedPromises = promises.map(p => Promise.resolve(p) 
     .then(
      val => ({ state: 'fulfilled', value: val }), 
      err => ({ state: 'rejected', reason: err }))); 
    return Promise.all(wrappedPromises); 
}