2015-06-01 24 views
8

Sto usando babel per traspondere il mio codice [email protected] e sono bloccato con promesse.Promise.allSettled in babel ES6 implementazione

Ho bisogno allSettled funzionalità tipo che potrei usare in q e bluebird o angular.$q per esempio.

Su core-js babele Promise, non esiste il metodo allSettled.

Attualmente sto usando q.allSettled come una soluzione:

import { allSettled } from 'q';

C'è qualcosa di simile in polyfill babele? In alternativa, quale è un buon algoritmo da me provare a implementare?

risposta

1

In alternativa, quale è un buon algoritmo per me provare a implementare?

  1. creare una nuova promessa con un executor function
  2. utilizzare una matrice contatore/risultato nel campo di applicazione della esecutore
  3. registrare un callback poi() con ogni promessa genitore salvare i risultati nella matrice
  4. determinazione/rifiutare promessa dal punto 1 quando il contatore indica che tutte le promesse fatte madri sono
+0

Bello, anche se per ora mi limiterò a utilizzare Q (che probabilmente sta facendo lo stesso). – Zlatko

+0

Riguardo al tuo passaggio 4, come potrei mai sapere rifiutare la nuova promessa? –

+0

@torazaburo hai ragione, non avresti mai rifiutato, questo è il punto di allSettled :) Forse un po 'di timeout, ma questo è un caso d'uso diverso e non riflette ciò che q.allSettled fa. – Zlatko

1

Ecco il mio tentativo di qualcosa di simile, I hav e il servizio Newsletter e nel mio caso ho voluto il mio allSettled promessa risolvere con una serie di tutti i risultati (rifiuti e risoluzioni), PER, una volta che tutti i email_promises sono regolate (tutte le email erano usciti):

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

Ecco un altro introito allo stesso funzionalità: spex.batch

il source code sarebbe troppo per ri-post qui, ecco è solo un esempio dalla batch processing di come usarlo:

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); 
    }); 

Questo uscite:

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

Ora facciamo fallire modificando getWord a questo:

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

Ora l'output è:

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

cioè l'intero array è risolta, la segnalazione risultati con indicizzazione.

E se invece di avere segnalato la ragione intera che noi chiamiamo getErrors():

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

allora l'uscita sarà:

REASON: [ 'World' ] 

Questo è solo per semplificare l'accesso rapido alla lista degli errori che si sono verificati .

12

Se date un'occhiata allo implementation of q.allSettled vedrete che è in realtà abbastanza semplice da implementare. Ecco come si potrebbe implementarlo utilizzando ES6 Promises:

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); 
} 
Problemi correlati