2016-08-05 15 views
5

Ich habe einige Code implementiert, wo einige synchrone Funktionen asynchronen Code folgt. Zum Beispiel:Sollte synchrone Code von Promise aufgerufen werden. Dann ein neues Versprechen erstellen

function processSomeAsyncData() { 
    asyncFuncCall() 
    .then(syncFunction) 
    .catch(error); 
} 

Wenn ich das richtig verstehe then ist auch ein Versprechen. Soll ich dann im synchronen Code auch ein Versprechen erstellen?

function syncFunction() { 
    const p = new Promise (function (resolve, reject) { 
    //Do some sync stuff 
    ... 
    resolve(data); 
    } 
    return p; 
} 

Wenn das nicht notwendig ist, wie lehnen Sie das Versprechen aus dem synchronen Code ab, wenn ein Fehler aufgetreten ist?

Antwort

6

Sie müssen kein neues Versprechen explizit erstellen. Es gibt einen einfacheren Weg.

Dieses Beispiel ist erfunden, weil es nie fehlschlagen wird, aber der Punkt ist, dass Sie keine Zusage erstellen müssen und Sie keine Auflösung (val) zurückgeben müssen.

function syncFunction() { 
    var j = "hi" 
    if(j){ 
    return j; 
    } 
    return new Error('i am an error'); 
} 

Dies funktioniert:

asyncFunction() 
    .then(syncFunction); 

Aber wenn du es getan hast umgekehrt:

syncFunction() 
    .then(asyncFunction); 

Sie würden Ihre syncFunction definieren:

function syncFunction() { 

    var j = "hi" 
    return new Promise((resolve, reject) => { 
    if(j){ 
     return resolve(j); 
    } 
    return reject('error'); 
    }) 
} 

Edit: Um allen Ungläubigen zu beweisen, gib dem Kerl einen Schnappschuss auf deinem Computer. Beweist, dass Ihnen diese vielen Optionen zur Verfügung stehen. :)

var Promise = require('bluebird'); 


function b(h) { 
    if(h){ 
     return h; 
    } 
    return Promise.resolve('hello from b'); 
} 

function a(z) { 
    return new Promise((resolve, reject)=> { 
     if(z){return resolve(z)}; 
     return resolve('hello from a'); 
    }) 
} 

a().then(b).then(x => console.log(x)).catch(e => console.log(e)); 
b().then(a).then(x => console.log(x)).catch(e => console.log(e)); 
+3

In Ihrem zweiten Beispiel wird 'new Promise' nicht benötigt, stattdessen sollten' Promise.resolve' und 'Promise.reject' Funktionen verwendet werden. – alexmac

+1

In Ihrem ersten Codebeispiel wird die Rückgabe eines Versprechens oder eines Wertes mit Sicherheit nicht mit der anschließenden Verkettung mit ".then" verbunden. – nils

+0

Ich mache einen schnellen Test lokal auf meinem Computer, um dies zu beweisen. Gib mir eine Sekunde. :) –

3

Es ist optional.

Wenn Sie eine Zusage von syncFunction zurückgeben, wird Ihr ursprüngliches Versprechen erst gelöst, nachdem das neue Versprechen aufgelöst wurde und alle von der neuen Zusage zurückgegebenen Werte an die nächste then in der Kette weitergeleitet werden.

Wenn Sie einen Nicht-Versprechen-Wert zurückgeben, wird dieser an die nächste then in der Kette weitergegeben.

Um innerhalb syncFunction zurückzuweisen, werfen Sie einfach eine Ausnahme.

+0

Wenn 'syncFunction' ein Versprechen gibt, sollte es zu' asyncFunction' umbenannt werden. – jib

2

Nein. Synchrone Funktionen können vom synchronen Code aufgerufen werden und sollten immer synchron ausfallen! Sie müssen in keiner Weise asynchronen Anrufern entsprechen. Wenn ein Fehler auftritt, werfen Sie einfach einen Fehler. Versuchen Sie es:

var asyncFuncCall =() => Promise.resolve(); 
 

 
function syncFunction() { 
 
    throw new Error("Fail"); 
 
} 
 

 
asyncFuncCall() 
 
    .then(syncFunction) 
 
    .catch(e => console.log("Caught: " + e.message));

Dies funktioniert, weil eine durch eine Funktion geworfen Ausnahme bestanden auf eine .then zu einer Ablehnung der Verheißung umgewandelt wird es soll zurückzukehren.

Darüber hinaus wird jeder Wert, der von einer Funktion zurückgegeben wird, die an .then übergeben wird, in ein Versprechen umgewandelt, das mit diesem Wert aufgelöst wird. Der Promise-Code, der die Funktion aufruft, kümmert sich darum.

Auf diese Weise können Sie ohne Probleme synchronen und asynchronen Code mischen:

asyncFuncCallOne() 
    .then(() => { 
    var x = syncFunction(); 
    return asyncFuncCallTwo(x); 
    }) 
    .catch(e => console.log(e.message)); 
+0

sollte dies die akzeptierte Antwort sein – Simoyw