2016-12-24 1 views
1

Ich bin ziemlich überzeugt, dass ich Missverständnisse, wie Versprechungen arbeiten, aber Lose haben, hat es versäumt, mein Problem zu lösen.infinite Schleife in Versprechen fangen mit Rückruffehler

Ich habe bestehenden Code, der ein anderes Modul aufruft, das gerade geändert wurde, um Versprechungen zu verwenden. die alte Version Mit sah wie folgt aus:

function(params, cb) { 
    ..... 
    asyncFunc(p1, (err, res) => { 
    if (!err) 
     ..... 
     cb(null,'msg'); 
    else 
     cb(err); 
    }; 
}; 

ändert dies:

function(params, cb) { 
    ..... 
asyncFuncwithPromise(p1).then(res = > { 
    ... // X 
    return cb(null,'msg'); 
}).catch(err => { 
    cb(err); 
}); 

Wenn der Code in Zeile X eine Ausnahme wirft diese in eine Endlosschleife von Fang geht() -> dann() . Entfernen des Rückrufs aus dem Catch und alles ist in Ordnung. Kann mir jemand erklären?

+0

Ich habe das nie erlebt, aber einen ähnlichen Code geschrieben. Hat etwas mit Ihrem 'asyncFuncwithPromise' und dem' cb' zu tun. Wie wird Ihre Funktion verwendet und wie 'asyncFuncwithPromise' definiert ist? –

+0

Brauchen Sie diese CB-Funktion zu sehen. Tut es, was Sie erwarten? Was gibt es zurück und/oder tun? –

+0

Danke, ich werde in die CB-Funktion (es ist nicht meins) graben, ich wollte nur überprüfen, dass die Grundlagen meiner Arbeit nicht fehlgeleitet sind. – mnsuk

Antwort

0

Nicht sicher, wie eine Endlosschleife hier erstellt würde, es sei denn, cb() ruft asyncFuncWithPromise().

Ich denke gerne Promise Callback-Ketten als zwei parallele Spuren. Verwenden Sie das Schlüsselwort return, um den Erfolg (then()) zu verfolgen. Verwenden Sie das Schlüsselwort throw, um den Fehler() zu verfolgen. Die Spur der Kette kann jederzeit umgeschaltet werden, Callbacks werden jedoch nur linear ausgeführt. Das heißt, ein früher in der Kette definierter Callback kann nicht ausgeführt werden, nachdem er später definiert wurde. Die Kette schiebt immer vorwärts und kann nicht in einen Zyklus eintreten.

Promise.resolve() 
    .then(()=>{ // 1S 
    if (Math.floor(Math.random() * 2)) 
     return "success"; // continue down "success" (then) track 
    else 
     throw "fail"; // continue down "failure" (catch) track 
    }) 
    .then(r=>{ // 2S 
    return "all good: " + r; 
    }) 
    .catch(e=>{ // 2F 
    // use 'return' to recover, continue down "success" track 
    return "recovered from error: " + e; 
    }) 
    .then(r=>{ // 3S 
    console.log(r); // always executed 
    }) 
    .catch(e=> { //3F 
    console.error(e); // never executed 
    }); 

In diesem Beispiel wird der endgültige Erfolg Link (3S) in der Kette mit console.log() immer, weil der return verwendete catch() Link (2F) ausgeführt werden, um die Kette wieder auf der Erfolgsspur zu kommen. Natürlich kann die Fehlerverfolgung für mehrere Verbindungen verfolgt werden, wenn jede Verbindung das Schlüsselwort throw verwendet.

Wenn ein neues mit dem Versprechen Promise Konstruktors entspricht die Erfolgs- und Fehlerspuren zunächst auf die resolve und reject in dem Resolver gelieferten Funktionen. So gibt es keinen Unterschied (funktionell) zwischen diesen:

function getPromise(...) { 
    return new Promise((resolve, reject)=>{ 
    /* do something... */ 
    if (condition) { 
     resolve(result); 
    } else { 
     reject(error); 
    } 
    }); 
} 

und diese:

function getPromise(...) { 
    return Promise.resolve().then(()=>{ 
    /* do something... */ 
    if (condition) 
     return result; 
    else 
     throw error; 
    }); 
} 

Der Unterschied zwischen diesen bezieht sich auf subtile Weise, wie Links in Versprechen Ketten verschieben Ereignis Rahmen zu Zeit laufen. Dies kann zwischen den Implementierungen variieren, aber normalerweise wird ein Rückruf an den nächsten Nachfolger des ausführenden Rahmens vertagt.

+0

Schönes Tutorial über einige Aspekte von Versprechen, aber ich bin mir nicht sicher, wie dies die Frage des OP beantwortet. – jfriend00

+0

@ jfriend00 heh, ja, ich erkenne es wahrscheinlich nicht die Frage. Aber von dem, was er präsentiert hat, gibt es keine Möglichkeit zu wissen, was passiert. Der einzige Weg, wie es in eine zyklische Schleife gehen kann, ist, wenn sein 'cb()' 'asyncFuncWithPromise()' aufruft. Ich habe versucht, Promise-Mechaniker mit Hoffnungen zu klären, dass es einen "Aha" -Moment auslösen könnte. – DRAB

+0

Ich schätze, ich sehe, dass Sie versuchen, zu helfen, aber wir möchten wirklich, dass das OP ihre Frage klärt, damit es allen klar ist, anstatt zu raten, was helfen könnte. – jfriend00

Verwandte Themen