Come funzionano le promesse in JavaScript?



asynchronous (3)

Ho appena implementato la mia prima funzione che restituisce una promessa basata su un'altra promessa in AngularJS e ha funzionato. Ma prima ho deciso di farlo, ho passato 2 ore a leggere e cercare di capire i concetti dietro le promesse. Ho pensato che se potessi scrivere un semplice pezzo di codice che simulasse il funzionamento delle promesse, sarei quindi in grado di comprenderlo concettualmente invece di essere in grado di usarlo senza sapere veramente come funziona. Non potrei scrivere quel codice.

Quindi, qualcuno potrebbe per favore illustrare in vaniglia JavaScript come funzionano le promesse?


Una promessa è fondamentalmente un oggetto con due metodi. Un metodo è per definire cosa fare, e uno è per dire quando farlo. Deve essere possibile chiamare i due metodi in qualsiasi ordine, quindi l'oggetto deve tenere traccia di quale è stato chiamato:

var promise = {
  isDone: false,
  doneHandler: null,
  done: function(f) {
    if (this.isDone) {
        f();
    } else {
        this.doneHandler = f;
    }
  },
  callDone: function() {
    if (this.doneHandler != null) {
        this.doneHandler();
    } else {
        this.isDone = true;
    }
  }
};

È possibile definire prima l'azione, quindi attivarla:

promise.done(function(){ alert('done'); });
promise.callDone();

Puoi prima attivare l'azione, quindi definirla:

promise.callDone();
promise.done(function(){ alert('done'); });

Demo: http://jsfiddle.net/EvN9P/

Quando si utilizza una promessa in una funzione asincrona, la funzione crea la promessa vuota, mantiene un riferimento ad essa e restituisce anche il riferimento. Il codice che gestisce la risposta asincrona attiverà l'azione nella promessa e il codice che chiama la funzione asincrona definirà l'azione.

Poiché uno di questi può avvenire in qualsiasi ordine, il codice che chiama la funzione asincrona può aggrapparsi alla promessa e definire l'azione ogni volta che lo desidera.


Probabilmente l'esempio più semplice di utilizzo delle promesse è simile a questo:

var method1 = (addings = '') => {
  return new Promise(resolve => {
    console.log('method1' + addings)
    resolve(addings + '_adding1');
  });
}
var method2 = (addings = '') => {
  return new Promise(resolve => {
    console.log('method2' + addings)
    resolve(addings + '_adding2');
  });
}

method1().then(method2).then(method1).then(method2);
// result:
// method1            
// method2_adding1    
// method1_adding1_adding2
// method2_adding1_adding2_adding1

Questo è di base delle basi. Avendolo, puoi sperimentare con gli scarti:

var method1 = (addings = '*') => {
  return new Promise((resolve, reject) => {
    console.log('method1' + addings)
    resolve(addings + '_adding1');
  });
}
var method2 = (addings = '*') => {
  return new Promise((resolve, reject) => {
    console.log('method2' + addings)
    reject();
  });
}
var errorMethod = () => {
  console.log('errorMethod')
}
method1()
.then(method2, errorMethod)
.then(method1, errorMethod)
.then(method2, errorMethod)
.then(method1, errorMethod)
.then(method2, errorMethod);
// result:
// method1*           
// method2*_adding1
// errorMethod
// method2*
// errorMethod
// method2*

Come possiamo vedere, in caso di errore viene attivata la funzione di errore (che è sempre il secondo argomento di then ) e quindi la successiva funzione in catena viene attivata senza alcun argomento specificato.

Per conoscenza avanzata ti invito here .


Per la semplicità di comprendere le promesse in Javascript. È possibile fare riferimento all'esempio seguente. Basta copiare incollare in un nuovo file php / html ed eseguire.

<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">

function test(n){
    alert('input:'+n);

    var promise = new Promise(function(fulfill, reject) {         
      /*put your condition here */
      if(n) {
        fulfill("Inside If! match found");
      }
      else {
        reject(Error("It broke"));
      }
    });
    promise.then(function(result) {
      alert(result); // "Inside If! match found"
    }, function(err) {
      alert(err); // Error: "It broke"
    });
}

</script>

</head>
<body>
<input type="button" onclick="test(1);" value="Test"/>

</body>
</html>
  1. Clicca sul pulsante Test ,
  2. Creerà nuova promessa,
  3. se la condizione sarà vera, adempierà la risposta,
  4. dopo quella promessa. Poi chiamato e basato sul compimento stamperà il risultato .
  5. In caso di rifiuto promessa, quindi restituisce il messaggio di errore.




asynchronous