Risposte:
Il modo tradizionale di gestire le chiamate asincrone in JavaScript è stato con i callback. Supponiamo che abbiamo dovuto effettuare tre chiamate al server, una dopo l'altra, per configurare la nostra applicazione. Con i callback, il codice potrebbe essere simile al seguente (supponendo una funzione xhrGET per effettuare la chiamata al server):
// Fetch some server configuration
xhrGET('/api/server-config', function(config) {
// Fetch the user information, if he's logged in
xhrGET('/api/' + config.USER_END_POINT, function(user) {
// Fetch the items for the user
xhrGET('/api/' + user.id + '/items', function(items) {
// Actually display the items here
});
});
});
In questo esempio, prima recuperiamo la configurazione del server. Quindi, in base a ciò, recuperiamo informazioni sull'utente corrente e infine otteniamo l'elenco degli elementi per l'utente corrente. Ogni chiamata xhrGET utilizza una funzione di richiamata che viene eseguita quando il server risponde.
Ora ovviamente più livelli di annidamento abbiamo, più difficile è leggere, eseguire il debug, mantenere, aggiornare e sostanzialmente lavorare con il codice. Questo è generalmente noto come l'inferno di callback. Inoltre, se abbiamo bisogno di gestire gli errori, dobbiamo eventualmente passare un'altra funzione a ciascuna chiamata xhrGET per dirgli cosa deve fare in caso di errore. Se volessimo avere un solo gestore di errori comune, questo non è possibile.
L'API Promise è stata progettata per risolvere questo problema di nidificazione e il problema della gestione degli errori.
L'API Promise propone quanto segue:
promiseoggetto.promiseoggetto avrà una thenfunzione che può accettare due argomenti, un success
gestore e un errorgestore.thenfunzione verrà chiamato una sola volta , al termine dell'attività asincrona.thenfunzione restituirà anche a promise, per consentire il concatenamento di più chiamate.value, che verrà passato alla funzione successiva come a argument, nella catena di promises.promise(effettua un'altra richiesta asincrona), il gestore successivo (esito positivo o errore) verrà chiamato solo al termine della richiesta.Quindi il codice di esempio precedente potrebbe tradursi in qualcosa di simile al seguente, usando promesse e il $httpservizio (in AngularJs):
$http.get('/api/server-config').then(
function(configResponse) {
return $http.get('/api/' + configResponse.data.USER_END_POINT);
}
).then(
function(userResponse) {
return $http.get('/api/' + userResponse.data.id + '/items');
}
).then(
function(itemResponse) {
// Display items here
},
function(error) {
// Common error handling
}
);
Propagare successo ed errore
Il concatenamento delle promesse è una tecnica molto potente che ci consente di ottenere molte funzionalità, come fare in modo che un servizio faccia una chiamata al server, esegua un po 'di postelaborazione dei dati e quindi restituisca i dati elaborati al controller. Ma quando lavoriamo con le
promisecatene, ci sono alcune cose che dobbiamo tenere a mente.
Considera la seguente ipotetica promisecatena con tre promesse, P1, P2 e P3. Ognuno promiseha un gestore di successo e un gestore di errori, quindi S1 ed E1 per P1, S2 ed E2 per P2 e S3 ed E3 per P3:
xhrCall()
.then(S1, E1) //P1
.then(S2, E2) //P2
.then(S3, E3) //P3
Nel normale flusso di cose, dove non ci sono errori, l'applicazione scorre attraverso S1, S2 e infine S3. Ma nella vita reale, le cose non sono mai così lisce. P1 potrebbe riscontrare un errore o P2 potrebbe riscontrare un errore, innescando E1 o E2.
Considera i seguenti casi:
• Riceviamo una risposta corretta dal server in P1, ma i dati restituiti non sono corretti o non ci sono dati disponibili sul server (pensate ad array vuoto). In tal caso, per la prossima promessa P2, dovrebbe attivare il gestore degli errori E2.
• Riceviamo un errore per promessa P2, innescando E2. Ma all'interno del gestore, abbiamo i dati dalla cache, assicurando che l'applicazione possa essere caricata normalmente. In tal caso, potremmo voler garantire che dopo E2 venga chiamato S3.
Quindi ogni volta che scriviamo un gestore di errori o di successo, dobbiamo effettuare una chiamata: data la nostra attuale funzione, questa promessa è un successo o un fallimento per il prossimo gestore nella catena di promesse?
Se vogliamo attivare il gestore del successo per la prossima promessa nella catena, possiamo semplicemente restituire un valore dal gestore del successo o dell'errore
Se, d'altra parte, vogliamo innescare il gestore degli errori per la prossima promessa nella catena, possiamo farlo usando un deferredoggetto e chiamando il suo reject()metodo
Ora che cos'è l'oggetto differito?
Gli oggetti differiti in jQuery rappresentano un'unità di lavoro che verrà completata in seguito, in genere in modo asincrono. Una volta completata l'unità di lavoro, l'
deferredoggetto può essere impostato su risolto o fallito.Un
deferredoggetto contiene unpromiseoggetto. Tramite l'promiseoggetto è possibile specificare cosa deve succedere al completamento dell'unità di lavoro. Puoi farlo impostando le funzioni di callbackpromisesull'oggetto.
Oggetti differiti in Jquery: https://api.jquery.com/jquery.deferred/
Oggetti differiti in AngularJs: https://docs.angularjs.org/api/ng/service/ $ q
la funzione then () è correlata alle "promesse Javascript" utilizzate in alcune librerie o framework come jQuery o AngularJS.
Una promessa è un modello per la gestione di operazioni asincrone. La promessa consente di chiamare un metodo chiamato "then" che consente di specificare le funzioni da utilizzare come callback.
Per ulteriori informazioni, consultare: http://wildermuth.com/2013/8/3/JavaScript_Promises
E per le promesse angolari: http://liamkaufman.com/blog/2013/09/09/using-angularjs-promises/
A promise can only succeed or fail onceIf a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called
Per quanto ne sappia, non esiste un then()metodo integrato in javascript(al momento della stesura di questo documento).
Sembra che qualunque cosa doSome("task")stia tornando ha un metodo chiamato then.
Se si registra il risultato di ritorno doSome()sulla console, si dovrebbe essere in grado di vedere le proprietà di ciò che è stato restituito.
console.log( myObj.doSome("task") ); // Expand the returned object in the
// console to see its properties.
AGGIORNAMENTO (a partire da ECMAScript6) : -
La .then()funzione è stata inclusa in javascript puro.
Dalla documentazione di Mozilla qui ,
Il metodo then () restituisce una promessa. Sono necessari due argomenti: funzioni di callback per i casi di successo e fallimento della Promessa.
L'oggetto Promise, a sua volta, è definito come
L'oggetto Promise viene utilizzato per calcoli differiti e asincroni. Una promessa rappresenta un'operazione che non è stata ancora completata, ma è prevista in futuro.
Cioè, Promiseagisce come un segnaposto per un valore che non è stato ancora calcolato, ma che sarà risolto in futuro. E la .then()funzione viene utilizzata per associare le funzioni da invocare sulla Promessa quando viene risolta, sia come successo che come fallimento.
.thenAllora non c'era un built-in , ma le promesse native stanno arrivando ora in ES6: html5rocks.com/en/tutorials/es6/promises
Ecco una cosa che ho fatto per me stesso per chiarire come funzionano le cose. Immagino che anche altri possano trovare utile questo esempio concreto:
doit().then(function() { log('Now finally done!') });
log('---- But notice where this ends up!');
// For pedagogical reasons I originally wrote the following doit()-function so that
// it was clear that it is a promise. That way wasn't really a normal way to do
// it though, and therefore Slikts edited my answer. I therefore now want to remind
// you here that the return value of the following function is a promise, because
// it is an async function (every async function returns a promise).
async function doit() {
log('Calling someTimeConsumingThing');
await someTimeConsumingThing();
log('Ready with someTimeConsumingThing');
}
function someTimeConsumingThing() {
return new Promise(function(resolve,reject) {
setTimeout(resolve, 2000);
})
}
function log(txt) {
document.getElementById('msg').innerHTML += txt + '<br>'
}
<div id='msg'></div>
quindi è uno stack di callback del metodo che è disponibile dopo che una promessa è stata risolta fa parte della libreria come jQuery ma ora è disponibile in JavaScript nativo e di seguito è la spiegazione di dettaglio come funziona
Puoi fare una Promessa in JavaScript nativo: proprio come ci sono promesse in jQuery, Ogni promessa può essere accatastata e quindi può essere chiamata con Risolvi e Rifiuta richiamate, Ecco come puoi concatenare le chiamate asincrone.
Ho modificato e modificato i documenti MSDN sullo stato di carica della batteria.
Quello che fa è provare a scoprire se il laptop o il dispositivo dell'utente sta caricando la batteria. poi viene chiamato e puoi fare il tuo lavoro dopo il successo.
navigator
.getBattery()
.then(function(battery) {
var charging = battery.charging;
alert(charging);
})
.then(function(){alert("YeoMan : SINGH is King !!");});
function fetchAsync (url, timeout, onData, onError) {
…
}
let fetchPromised = (url, timeout) => {
return new Promise((resolve, reject) => {
fetchAsync(url, timeout, resolve, reject)
})
}
Promise.all([
fetchPromised("http://backend/foo.txt", 500),
fetchPromised("http://backend/bar.txt", 500),
fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
let [ foo, bar, baz ] = data
console.log(`success: foo=${foo} bar=${bar} baz=${baz}`)
}, (err) => {
console.log(`error: ${err}`)
})
Definizione :: then è un metodo utilizzato per risolvere i callback asincroni
questo è introdotto in ES6
Trova la documentazione corretta qui Promesse Es6
thenproviene e come funziona. È necessario migliorare la risposta per fornire tali dettagli.
Sospetto che doSome restituisca questo, che è myObj, che ha anche un metodo allora. Concatenamento con metodo standard ...
se doSome non lo restituisce, essendo l'oggetto su cui è stato eseguito doSome, ti assicuro che sta restituendo un oggetto con un metodo then ...
come sottolinea @patrick, non esiste nessun () per js standard
doSome ("task") deve restituire un oggetto promise e quella promessa ha sempre una funzione then. Quindi il tuo codice è proprio così
promise.then(function(env) {
// logic
});
e sai che questa è solo una normale chiamata alla funzione membro.
.then restituisce una promessa nella funzione asincrona.
Un buon esempio sarebbe:
var doSome = new Promise(function(resolve, reject){
resolve('I am doing something');
});
doSome.then(function(value){
console.log(value);
});
Per aggiungere un'altra logica, puoi anche aggiungere la reject('I am the rejected param')chiamata alla funzione e console.log.
In questo caso then()è un metodo di classe dell'oggetto restituito dal doSome()metodo.
La funzione ".then ()" è ampiamente utilizzata per gli oggetti promessi nella programmazione di Asynchoronus per le app di Windows 8 Store. Per quanto ho capito, funziona in qualche modo come una richiamata.
Trova i dettagli in questo documento http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx
Di causa potrebbe anche essere il nome per qualsiasi altra funzione definita.
Un altro esempio:
new Promise(function(ok) {
ok(
/* myFunc1(param1, param2, ..) */
)
}).then(function(){
/* myFunc1 succeed */
/* Launch something else */
/* console.log(whateverparam1) */
/* myFunc2(whateverparam1, otherparam, ..) */
}).then(function(){
/* myFunc2 succeed */
/* Launch something else */
/* myFunc3(whatever38, ..) */
})
La stessa logica usando la scorciatoia delle funzioni freccia:
new Promise((ok) =>
ok(
/* myFunc1(param1, param2, ..) */
)).then(() =>
/* myFunc1 succeed */
/* Launch something else */
/* Only ONE call or statment can be made inside arrow functions */
/* For example, using console.log here will break everything */
/* myFunc2(whateverparam1, otherparam, ..) */
).then(() =>
/* myFunc2 succeed */
/* Launch something else */
/* Only ONE call or statment can be made inside arrow functions */
/* For example, using console.log here will break everything */
/* myFunc3(whatever38, ..) */
)
Sono in ritardo di circa 8 anni, beh ... comunque, non so davvero cosa faccia allora () ma forse MDN potrebbe avere una risposta. In realtà, potrei davvero capirlo un po 'di più.
Questo ti mostrerà tutte le informazioni (si spera) di cui hai bisogno. A meno che qualcuno non abbia già pubblicato questo link. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
Il formato è promise.prototype.then () La promessa e il prototipo sono una specie di variabili simili ma non come variabili in javascript, intendo come altre cose vanno lì come navigator.getBattery (). Then () dove questo esiste realmente ma è usato a malapena sul Web, questo mostra gli stati della batteria del dispositivo, ulteriori informazioni e altro su MDN se sei curioso.