2016-04-08 16 views
2

Ich habe mit Versprechungen zu spielen, aber ich habe Probleme zu verstehen, was mit dem folgenden Code geschieht:JavaScript Versprechen und SetTimeout

function a() { 
    return new Promise(function (resolve, reject) { 
     resolve("hi from a!"); 
    }); 
} 

function b() { 
    return new Promise(function (resolve, reject) { 
     setTimeout(function() { 
      resolve("hi from b!"); 
     }, 5000); 
    }); 
} 

function c() { 
    return new Promise(function (resolve, reject) { 
     setTimeout(function() { 
      resolve("hi from c!"); 
     }, 1000); 
    }); 
} 

a().then(function (resultFromA) { 
    console.log("a() responded with: " + resultFromA); 
    b(); 
}).then(function (resultFromB) { 
    console.log("b() responded with: " + resultFromB); 
    c(); 
}).then(function (resultFromC) { 
    console.log("c() responded with: " + resultFromC); 
}); 

ich diese a() responded with: hi from a! sofort Ausgang erwarten, zusammen mit b() responded with: hi from b! und c() responded with: hi from c! nach ihre jeweiligen setTimeout() Brände. Allerdings bekomme ich folgende sofort folgende Ausgabe:

a() geantwortet mit: hi from a!

b() reagierte mit: undefined

c() mit antwortete:

Ich dachte, dass .then() wartet auf diesen Versprechungen nicht definiert, aber es ist nicht. Jede Hilfe wäre willkommen.

Antwort

12

Sie müssen return b() und return c() von innerhalb Ihrer then Handler.

then nur "ersetzt" das erste Versprechen mit einem nachfolgenden Versprechen, das von seinem Rückruf zurückgegeben wird.

Wenn Ihr then Rückruf nicht return ein Versprechen, dann gilt die then auf die ursprünglichen Versprechen, und es wird sofort unabhängig vom Inhalt/Ergebnis des vorherigen then Rückrufs ausgeführt werden. Grundsätzlich

...

a().then(function() { 
    b() 
}).then(# This "then" is chained off of a's promise 

Während umgekehrt:

a().then(function() { 
    return b() 
}).then(# This "then" is chained off of b's promise 
+0

Diese Erklärung ist nicht richtig. Die Funktion 'then()' gibt immer ein neues Versprechen zurück. Im obigen Fall ('b()') ist der Rückgabewert der Funktion jedoch 'undefined', der in eine neue Promise eingeschlossen ist. Es sieht so aus, als ob die zweite Verheißung von der 'a()' Verheißung abgekettet wird, weil der Rumpf der '.then()' Funktion synchron abschließt, also wird der dann sofort beendet. –

4

Sie müssen return promises zu Kette ihnen:

a().then(function (resultFromA) { 
    console.log("a() responded with: " + resultFromA); 
    // return b() promise 
    return b(); 
}).then(function (resultFromB) { 
    console.log("b() responded with: " + resultFromB); 
    // return c() promise 
    return c(); 
}).then(function (resultFromC) { 
    console.log("c() responded with: " + resultFromC); 
}); 
3

Sie haben vergessen, aus Funktionsaufruf zurückzukehren. Javascript-Funktion gibt nicht implizit zurück.

function a() { 
    return new Promise(function (resolve, reject) { 
     resolve("hi from a!"); 
    }); 
} 

function b() { 
    return new Promise(function (resolve, reject) { 
     setTimeout(function() { 
      resolve("hi from b!"); 
     }, 5000); 
    }); 
} 

function c() { 
    return new Promise(function (resolve, reject) { 
     setTimeout(function() { 
      resolve("hi from c!"); 
     }, 1000); 
    }); 
} 

a().then(function (resultFromA) { 
    console.log("a() responded with: " + resultFromA); 
    return b(); // return 
}).then(function (resultFromB) { 
    console.log("b() responded with: " + resultFromB); 
    return c(); // return 
}).then(function (resultFromC) { 
    console.log("c() responded with: " + resultFromC); 
}); 
+0

Mein Problem war, dass ich aus irgendeinem Grund dachte, dass das 'then' auf alle Versprechungen im lokalen Bereich wartet, bis es wirklich" nur "returned ist. Ich habe ursprünglich nicht versucht, 'return b()' oder 'return c()' zu machen. –

+0

"Javascript-Funktion gibt nicht implizit zurück." Nicht ganz richtig. Arrow-Funktionen * do * geben implizit zurück, wenn der Body ein einzelner Ausdruck ist: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Function_body –