Confrontiamo l'esempio promessa di un puro esempio Javascript:
// First we need a convenience function for W3C's fiddly XMLHttpRequest.
// It works a little differently from the promise framework. Instead of
// returning a promise to which we can attach a handler later with .then(),
// the function accepts the handler function as an argument named 'callback'.
function requestSomeDataAndCall(url, callback) {
var req = new XMLHttpRequest();
req.onreadystatechange = resHandler;
req.open("GET", url, false);
req.send();
function resHandler() {
if (this.readyState==4 && this.status==200) {
callback(this);
} else {
// todo: Handle error.
}
}
}
requestSomeDataAndCall("http://example.com/foo", function(res){
setTimeout(function(){
var data = JSON.parse(res.responseText);
setTimeout(function(){
var price = data.price;
setTimeout(function(){
print("The price is "+price);
},10);
},10);
},10);
});
Come Norbert Hartl ha sottolineato, JSON.parse() si bloccherà il browser per stringhe di grandi dimensioni. Quindi ho usato setTimeout() per ritardarne l'esecuzione (dopo una pausa di 10 millisecondi). Questo è un esempio della soluzione di Kris Kowal. Consente il completamento del thread Javascript corrente, liberando il browser per presentare le modifiche al DOM e scorrere la pagina per l'utente, prima dell'esecuzione del callback.
spero che il quadro promessa commonjs inoltre usa qualcosa come setTimeout, altrimenti le promesse più tardi nel l'esempio del articolo sarà davvero funzionare in modo sincrono come temuto.
La mia alternativa sopra sembra piuttosto brutto, con i processi successivi che richiedono un ulteriore rientro. Ho ristrutturato il codice, in modo che possiamo fornire la nostra catena di processo tutto in un unico livello:
function makeResolver(chain) {
function climbChain(input) {
var fn = chain.shift(); // This particular implementation
setTimeout(function(){ // alters the chain array.
var output = fn(input);
if (chain.length>0) {
climbChain(output);
}
},10);
}
return climbChain;
}
var processChain = [
function(response){
return JSON.parse(response.body);
},
function(data){
return data.price; // get the price
},
function(price){
print("The price is " + price);
}
];
var climber = makeResolver(promiseChain);
requestSomeDataAndCall("http://example.com/foo", climber);
speravo di dimostrare che tradizionale previsionali passaggio di callback in JavaScript è più o meno equivalente a promesse. Tuttavia, dopo due tentativi, sembra che abbia mostrato, con riferimento alla nitidezza del codice nell'esempio originale, che le promesse sono una soluzione molto più elegante!
È hanno ragione, non ha senso usare le promesse per le operazioni sincrone. Quindi il risultato dovrebbe essere uguale. Ma poi è un esempio e illustra l'uso della promessa. Per il codice che è in esecuzione dopo il tuo esempio, c'è davvero una differenza. Se è necessario eseguire qualcosa dopo l'esempio di quello che è possibile fare (utilizzando l'approccio promettente) senza sapere nulla su ciò che sta facendo il codice di esempio –