2016-02-14 24 views
6

capisco promette di esistere in uno dei tre stati: A Promise può essere sia in attesa di (non risolto), soddisfatte (risolto con successo) o respinto (risolto senza successo).JS Promesse: compiere vs Resolve

Leggendo il A+ Promise Spec e MDN's documentation, mi sono confuso che entrambi riconoscono l'soddisfatte e respinti stati, ma nella definizione del costruttore Promessa specificano due callback: a risolvere e raccolgano le. Sembra che stiamo usando questi due termini in modo intercambiabile; non sono.

non implica il successo:

re·solve /rəˈzälv/ verb 
1. settle or find a solution to (a problem, dispute, or contentious matter). 

implica il successo:

ful·fill /fo͝olˈfil/ verb 
1. bring to completion or reality; achieve or realize (something desired, promised, or predicted). 
2. carry out (a task, duty, or role) as required, pledged, or expected. 

Perché stiamo usando volontà qui quando siamo in realtà soddisfare ing Promessa? Esiste un'istanza in cui il valore che passiamo a risolve potrebbe comportare la promessa di rifiuto ed?

+0

Vedere http://stackoverflow.com/questions/35042068/why-is-onjected-not-called-following-promise-all-where-promise-reject-incl – guest271314

+1

Questo collegamento non sembra rilevante. Puoi elaborare? – rrowland

+1

_ "Mi è venuto in mente che forse se passassi un errore alla richiamata risoluzione, rifiuterebbe la Promessa." _ La 'Promessa' è stata risolta con' Errore' come valore, la 'Promessa' non è stata rifiutata. – guest271314

risposta

2

Un risolto Promise avere un valore di un Error non converte automaticamente il Promise al respinto Promise

var p = Promise.resolve(new Error("rejected")); 
 
p.then(function(data) { 
 
    console.log(data, p) 
 
})


Vedi anche States and fates


Se è possibile includere informazioni su come la risoluzione potrebbe essere utilizzata per rifiutare la Promessa piuttosto che soddisfarla, considererei questa una risposta completa .

Non

certo su ragioni a favore o atteso dei resolve per rifiutare una Promise?Anche se l'approccio più semplice per raggiungere questo obiettivo sarebbe quello di passare reject come parametro quando resolve chiamato Promise.resolve(Promise.reject(/* Error here */))

var _reject = function(err) { 
 
    return Promise.reject(err) 
 
} 
 

 
var resolver = function(resolve, reject) { 
 
    return resolve(_reject(new Error("reject within resolve"))) 
 
} 
 

 
var p = new Promise(resolver); 
 

 
p.then(function(data) { 
 
    console.log("resolved", data) 
 
},function(data) { 
 
    console.log("rejected:", data, "promise:", p) 
 
})

Se risultato atteso è quello di individuare gli errori o un rifiutato Promise passato a resolve in cui possono essere collegati i gestori , pur mantenendo il PromiseStatus, potrebbe utilizzare l'evento unhandledrejection, Promise.reject direttamente o in chrome/chromium 49+ potrebbe utilizzare PromiseRejectionEvent

window.addEventListener("unhandledrejection", function(event) { 
 
    // handle unhandled rejected `Promise` 
 
    console.log("unhandledrejection:", event.reason, event.promise); 
 
}); 
 

 
Promise.resolve(new PromiseRejectionEvent("Error", { 
 
    // unhandled `rejected` `Promise` 
 
    promise: Promise.reject(new Error("custom rejection")), 
 
    reason: "custom rejection" 
 
    })) 
 
    .then(function(data) { 
 
    // `PromiseRejectionEvent` contains a `rejected` 
 
    // `Promise` , which triggers `"unhandledrejection"` event 
 
    // to handle rejected `Promise` here, resolve `.promise` 
 
    // object of `PromiseRejectionEvent` 
 
    console.log("resolved:", data); 
 
    }, function(err) { 
 
    console.log("rejected", err) 
 
})

potrebbe anche throw un Error all'interno Promise costruttore senza utilizzare resolve o reject, che deve essere maneggiato da onRejected o catch

new Promise(function(resolve, reject) { 
 
    throw new Error("reject within Promise constructor") 
 
}) 
 
// catch here handles `Error` from `Promise` constructor 
 
// will be `resolved` at `.then()` if `Error` not `throw`n to `.then()` 
 
// .catch(function(e) { 
 
// console.log("caught error:", e); 
 
    /* return e : pass `e` to `.then()` as `resolved` `Promise` */ 
 
    /* throw e : pass `e` to `.then()` as `rejected` `Promise` */ 
 
//}) 
 

 
.then(function(data) { 
 
    console.log("resolved:", data) 
 
}, function(err) { 
 
    console.log("rejected:", err); 
 
    throw err 
 
}) 
 
.catch(function(e) { 
 
    console.log("caught error:", e); 
 
    /* return e : pass `e` to `.then()` as `resolved` `Promise` */ 
 
    /* throw e : pass `e` to `.then()` as `rejected` `Promise` */ 
 
})


Spiegazione: Esistono numerosi approcci per la gestione di oggetti risolti e rifiutati Promise, a seconda dell'applicazione e dei risultati previsti.

+0

Come chiarito nei commenti sopra, si tratta di una domanda che non ho posto. Stavo usando questo esempio per illustrare che la funzione 'resolve' sta effettivamente eseguendo la funzione' fulfill' mentre passa semplicemente lungo il valore, ovvero adempiendo alla Promessa – rrowland

+0

@rrowland Is _ "C'è un caso da fare per i termini più recenti ? "_ la domanda vera? – guest271314

+0

Mi rendo conto che la mia domanda iniziale era vaga e gli esempi che ho usato potrebbero essere stati fuorvianti. Ho aggiornato la mia domanda. Ho già scoperto la risposta da solo, ma la tua risposta sembra sulla strada giusta. Se potessi includere informazioni su come 'resolve' potrebbe essere usato per rifiutare la Promessa piuttosto che soddisfarla, considererei questa una risposta completa. – rrowland

1

Penso che sia normale dire che la promessa è stata risolta o risolta. La risoluzione della promessa è il processo in cui la promessa passa dallo stato pending e acquisisce un valore associato a detto stato. Quindi, se una promessa è o fulfilled o rejected, sarà una promessa risolta (dato che il processo di risoluzione è terminato). Se una promessa entra nel processo di risoluzione e non passa mai a nessun altro stato, si dice che la promessa non è risolta (il processo di risoluzione non è mai terminato).

Per quanto riguarda gli altri termini rejected o fulfilled, sono gli altri due stati in cui la promessa pending può passare da. reject è abbastanza evidente IMO, gestisce i casi in cui si suppone che accada. Ora sono d'accordo che fulfill può essere un po 'ambiguo perché potrebbe semplicemente significare che la promessa è stata completata con successo (come in fase di risoluzione). Non si suppone che descriva il processo di risoluzione ma il successo (o l'assenza di errore) del compito in questione.

Il processo di risoluzione (per risolvere una promessa) può essere osservato nel A+ spec.

Modifica.

Il motivo per cui le persone utilizzano in genere resolve come nome del primo argomento perché il callback è passato mentre il primo argomento richiama il processo di risoluzione. Non adempie alla promessa (la promessa può ancora essere respinta), inizia a risolvere la promessa. Il meccanismo reject non è specificato nelle specifiche, in realtà è un cortocircuito del processo di risoluzione in modo che la promessa sia risolta con reject (non effettivamente risolto).

Ecco alcuni esempi in cui viene rifiutato p utilizzando resolve:

Questo è il punto 2.3.1.

var p = new Promise(resolve => setTimeout(() => resolve(p), 0)); 

Questo è il punto 2.3.2.3.

var p = Promise.resolve(Promise.reject('reason')); 

Questo è il punto 2.3.3.2.

var thenable = { get then() { throw new Error(); } } 
var p = Promise.resolve(thenable); 

Questo è punto 2.3.3.3.3

var thenable = { 
    then: function(resolvePromise, rejectPromise){ 
     rejectPromise(new Error()); 
    } 
} 
var p = Promise.resolve(thenable); 

Questo è il punto 2.3.3.4.2

var thenable = { 
    then: function(){ 
     throw new Error(); 
    } 
} 
var p = Promise.resolve(thenable); 

ho usato Promise.resolve qui invece del primo argomento della funzione passata giù al costruttore promessa, ma dovrebbe essere lo stesso Molte volte la funzione resolve tramandata al costruttore è:

var p = this; 
var cb = function(x){ 
    resolve(p, x); 
} 

Ovviamente si può annotare questi test come:

var p = new Promise(function(resolve){ 
    resolve(thenable); 
}); 
2

Siamo in grado di risolvere una promessa con un'altra promessa.

Per rispondere alla prima domanda, prima domanda: Sì, c'è un'istanza in cui il valore che passiamo a risolvere potrebbe comportare la promessa di respinta, e cioè se la passiamo a una promessa respinta, ad es. Promise.reject().

Per rispondere alla tua prima domanda di non è determinazione e soddisfano lo stesso: Si consideri il caso in cui il valore si passa da risolvere è un attesa promessa. In questo caso la nostra promessa sarà non accontentarsi immediatamente a seguito:

a().then(() => new Promise(setTimeout)).catch(e => console.error(e)); 

In questo caso diciamo che una promessa è "deliberato di" un'altra promessa, e rimane in attesa.

tutto questo succede alle nostre spalle all'interno then, quindi potrebbe essere più facile guardare un caso epoca in cui a non supporta promesse (prende callback), e noi non appiattire le cose correttamente:

// Old times and unflattened for exposition: 
new Promise((resolve, reject) => a(function(result) { 
    resolve(new Promise(setTimeout)); 
}, reject)) 
.then(() => console.log("after setTimeout")) 
.catch(e => console.error(e)); 

Qui vediamo più chiaramente che la risoluzione viene chiamata con un'altra promessa.È importante sottolineare che il risolto promessa non soddisfare e fuoco il messaggio "after setTimeout" fino a quando il secondo risolve promessa (con un non-promessa undefined valore da setTimeout), a quel punto entrambe le promesse diventano soddisfatte (in altre parole: questi due promesse appena formate a resolve chain).

Questa è la chiave per capire che risolto è diverso da soddisfatte o anche stabilirono (soddisfatte o respinto, non in attesa).

Da States and Fates:

  • stati: soddisfatte, respinto, attesa.
  • destini: risolto, irrisolto.

Il destino riferisce a se è stato raggiunto il destino di una singola promessa, e non corrisponde direttamente a qualsiasi transizione di stato, a causa di catene resolve.

+0

Cosa succede se 'Promise.reject()' viene passato a 'resolve'? Non farà sì che anche questa Promessa sia respinta? – rrowland

+0

Per rispondere alla mia stessa domanda: 'resolve (Promise.reject())' risolverà il destino della Promessa in un'altra Promessa che viene respinta, con conseguente rifiuto di questa Promessa.Penso che il fattore importante e fuorviante sia che 'resolve' si riferisce a una transizione del destino e' reject' si riferisce a una transizione di stato. Mi sembra che solo 'resolve' sia necessario e' reject' è una funzione di zucchero confuso per 'resolve (Promise.reject())'. – rrowland

+0

Può essere immediatamente rifiutato, la specifica non dice da nessuna parte che il rifiuto debba avvenire in modo asincrono sebbene i gestori di "then" vengano sempre chiamati in modo asincrono. – MinusFour