2014-12-31 14 views
173

Qual è la differenza tra:Qual è la differenza tra il valore di ritorno o Promise.resolve da allora()

new Promise(function(res, rej) { 
 
    res("aaa"); 
 
    }) 
 
    .then(function(result) { 
 
    return "bbb"; 
 
    }) 
 
    .then(function(result) { 
 
    console.log(result); 
 
    });

e questo:

new Promise(function(res, rej) { 
 
    res("aaa"); 
 
    }) 
 
    .then(function(result) { 
 
    return Promise.resolve("bbb"); 
 
    }) 
 
    .then(function(result) { 
 
    console.log(result); 
 
    });

Lo chiedo mentre sto assumendo un comportamento diverso Usando il servizio Angular e $ http con concatenamento .then(). Un po 'troppo codice quindi prima l'esempio sopra.

+1

Che "comportamento diverso" stai vedendo? Entrambi gli esempi dovrebbero funzionare e comportarsi all'incirca allo stesso modo. 'Promise.resolve()' nel secondo esempio non è necessario. – JLRishe

+4

@pixelbits Non c'è niente di sbagliato nel restituire una promessa da un "allora" gestore, infatti, è un aspetto chiave delle specifiche di promessa che puoi fare. –

+0

Si noti che questo funziona con nidificato arbitrariamente 'then's - il termine 'other languages' per questo è che' then' è sia un 'map' che un' flatMap'. –

risposta

60

Entrambi i tuoi esempi dovrebbero comportarsi più o meno lo stesso.

Un valore restituito all'interno di un gestore then() diventa il valore di risoluzione della promessa tornato da quel then(). Se il valore restituito all'interno di .then è una promessa, la promessa restituita da then() "adotterà lo stato" di tale promessa e risolverà/respingerà esattamente come fa la promessa restituita.

Nel tuo primo esempio, si ritorna "bbb" nel primo then() gestore, in modo "bbb" è passato attraverso la prossima then() gestore.

Nel secondo esempio, si restituisce una promessa che viene immediatamente risolta con il valore "bbb", quindi "bbb" viene passato al successivo gestore then(). (Il Promise.resolve() qui è estraneo).

Il risultato è lo stesso.

Se puoi mostrarci un esempio che mostra in realtà un comportamento diverso, possiamo dirti perché questo sta accadendo.

90

La regola è, se la funzione che si trova nel gestore then restituisce un valore, la promessa si risolve/respinge con quel valore, e se la funzione restituisce una promessa, ciò che accade è, il prossimo then clausola sarà la then clausola la promessa la funzione restituita, quindi, in questo caso, il primo esempio cade attraverso la normale sequenza di thens e stampa i valori come ci si potrebbe aspettare, nel secondo esempio, l'oggetto promessa che viene restituito quando si esegue Promise.resolve("bbb") è quindi il then che viene richiamato durante la concatenazione (per tutti gli effetti). Il modo in cui funziona in realtà è descritto di seguito in modo più dettagliato.

Citando promesse/A + spec: Procedura di risoluzione

La promessa è un'operazione astratta prendendo in ingresso una promessa e un valore, che indicheremo come [[Resolve]](promise, x). Se x è una variabile, tenta di fare la promessa ad adottare lo stato di x, partendo dal presupposto che x si comporta almeno in qualche modo come una promessa. In caso contrario, soddisfa la promessa con il valore x.

Questo trattamento di variabili consente l'implementazione di promettenti interoperabilità, a condizione che espongano un metodo Promises/A + -complicant. Consente inoltre implementazioni Promises/A + per "assimilare" implementazioni non conformi con metodi ragionevoli.

La cosa fondamentale da notare qui è questa linea:

se x è una promessa, adotta il proprio stato di [3.4]

link: https://promisesaplus.com/#point-49

+2

"Adotta il suo stato" è un modo sintetico e utile per esprimere il comportamento quando un gestore 'then' restituisce una promessa. +1 per il riferimento alle specifiche. –

+40

In realtà - la parte rilevante delle specifiche qui è il fatto che '[[Resolve]]' è chiamato sia su 'then'ables che su valori così essenzialmente esso racchiude un valore con la promessa così 'return' aaa '' è lo stesso come 'return Promise.resolve (" aaa ")' e 'return Promise.resolve (" aaa ")' è lo stesso di 'return Promise.resolve (Promise.resolve (" aaa "))' - poiché la risoluzione è chiamata idempotent su un valore più di una volta ha lo stesso risultato. –

+5

@Benjamin Gruenbaum significa che return '" aaa "' e 'return Promise.resolve (" aaa ")' sono intercambiabili in 'then'ables in ogni caso? – CSnerd

35

È ha già una buona risposta formale Ho pensato che dovrei aggiungerne uno corto.

Le seguenti cose sono identiche con Promises/A+ promesse:

  • Calling Promise.resolve (Nel tuo caso angolare che è $q.when)
  • chiamando il costruttore promessa e risolvere nel suo risolutore. Nel tuo caso è new $q.
  • Restituzione di un valore da una richiamata then.
  • Chiamare Promise.all su un array con un valore e quindi estrarre quel valore.

Così i seguenti sono tutti identici per una promessa o un valore normale X:

Promise.resolve(x); 
new Promise(function(resolve, reject){ resolve(x); }); 
Promise.resolve().then(function(){ return x; }); 
Promise.all([x]).then(function(arr){ return arr[0]; }); 

E non è una sorpresa, la specifica promesse si basa sul Promise Resolution Procedure che consente una facile interoperabilità tra biblioteche (come $ q e promesse native) e rende la tua vita nel complesso più facile. Ogni volta che si verifica una risoluzione di promessa, si verifica una risoluzione che crea coerenza complessiva.

12

In termini semplici, all'interno di una funzione then gestore:

A) Quando x è un valore (numero, stringa, ecc):

  1. return x equivale a return Promise.resolve(x)
  2. throw x è equivalente a return Promise.reject(x)

B) Quando x è una promessa che è già risolta (non in attesa di più):

  1. return x è equivalente a return Promise.resolve(x), se la promessa è stata già risolta.
  2. return x è equivalente a return Promise.reject(x), se la Promessa è già stata rifiutata.

C) Quando x è una promessa che è in attesa:

  1. return x restituirà una promessa sospeso, e si valuterà sul successivo then.

Maggiori informazioni su questo argomento su Promise.prototype.then() docs.

Problemi correlati