2016-10-17 5 views
1

Ich habe versucht, Promise.all zu arbeiten, ohne Erfolg mit einer Liste von Versprechen, so versuchte es stattdessen mit nur einem Array von einem Versprechen, und ich bekomme das gleiche Problem:Promise.all nicht zurück

let tasks = []; 
    tasks.push(function(resolve, reject){ 
    superagent 
    .post(URL_ROOT + url_path) 
    .send(data) 
    .end(function(err, res){ 
      if(err) 
      reject(err); 

      assert.equal(res.status, status.UNAUTHORIZED); //401 
      console.log('Promise completed successfully'); 
      resolve(); 
    }); 
    }); 


Promise.all([ 
    new Promise(tasks[0]) 
]).then(function(){ 
    console.log("Done"); 
    done(); 
}) 
.catch(function(reason){ 
    throw new Error(reason); 
}); 

"Versprechen erfolgreich abgeschlossen" druckt einfach, aber dann hängt es nur, und "Fertig" wird nie gedruckt.

Jede Hilfe würde sehr geschätzt werden.

+4

Es macht keinen Sinn. Wenn "Versprechen erfolgreich abgeschlossen" gedruckt wird, sollte auch "Fertig" gedruckt werden. – Lewis

+0

Beachten Sie, dass Ihre Zusage niemals zurückgewiesen wird, wenn Ihre Assertion ausgelöst wird, und dass der "catch" -Rückruf bedeutungslos ist (wahrscheinlich sollte er mit einem Fehler "fertig" sein). – Bergi

+0

@Bergi Ich muss zugeben, dass ich meine Versprechungen nicht dargelegt habe wie dies, und würde die Promise direkt zum Aufgaben-Array hinzufügen. Aber das OP sagte, er bekommt "Promise erfolgreich abgeschlossen" so die Behauptung, obwohl falsch kann hier nicht das Problem sein, da die Entschlossenheit sicher auch getroffen worden wäre. Das superagente Zeug zu entfernen, funktioniert in der Tat für mich. Verwendet das OP vielleicht eine bestimmte Promise-Lib, die nicht richtig funktioniert? – Keith

Antwort

5

Blick auf den Knoten-Handler:

.end(function(err, res){ 
     if(err) 
     reject(err); 

     assert.equal(res.status, status.UNAUTHORIZED); //401 
     console.log('Promise completed successfully'); 
     resolve(); 
}); 

Dies wird sowohl reject anrufen und resolve wenn ein Fehler aufgetreten ist (und die Geltendmachung gelingt). Ich vermute das in Ihrem Fall, also wird das Versprechen abgelehnt (da Abweisung vor Auflösung aufgerufen wird), der Code geht weiter und druckt Promise completed successfully.

Danach läuft das Versprechen Kette in die Ablehnung Handler:

.catch(function(reason){ 
    throw new Error(reason); 
}); 

Aber dieser Code nicht alles tun, wie es in einem Versprechen Fortsetzung werfen wird in den resultierenden Versprechen in eine Ablehnung übersetzen, die versprechen, ist hier vergessen.

die folgenden Versuchen Sie, meine Theorie zu bestätigen, und sehen, ob es protokolliert:

.catch(function(reason){ 
    console.log("Promise rejected"); 
    throw new Error(reason); 
}); 

Um dies zu beheben, alles, was Sie tun müssen, ist Ihr Code ein bisschen restrukturieren:

.end(function(err, res){ 
    if(err) { 
    reject(err); 
    } else { 
    resolve(); 
    assert.equal(res.status, status.UNAUTHORIZED); //401 
    console.log('Promise completed successfully'); 
    } 
}); 

So Sie haben die asynchrone Aufgabe in eine ordnungsgemäße Zusage konvertiert (möglicherweise müssen Sie auch .on("error", reason => reject(reason)) behandeln) und einen Fehlerhandler in die catch-Klausel einfügen.

Wenn Sie immer noch den Fehler an den globalen Fehlerhandler übergeben werden sollen, können das Beste, was Sie tun, ist es in einem setTimeout zu tun, so das Versprechen Rückruf kann den Fehler nicht fangen und übersetzen:

.catch(function(reason) { 
    setTimeout(() => { 
    throw new Error(reason); 
    }, 0); 
}); 
+0

Ah, danke, es funktioniert jetzt :) Ich habe nicht realisiert, dass die Ausführung nach einer Ablehnung fortgesetzt werden würde, oder dass, wenn nicht autorisiert, err nicht null ist. – Nodeocrat

+0

Auch die Assertion und das Protokoll sollten in einen 'then'-Handler geschrieben werden, nicht in den Resolver-Callback. – Bergi

+0

Crikey hatte diese gestern, jemand, der eine Zurückweisung annimmt(), schließt die Funktion kurz. Eine andere Option ist natürlich das 'if (err) return reject (err);' Ich weiß, dass es persönliche Vorlieben sind, nur verhindert es massive wenn dann auch andere Einrückungen. – Keith

Verwandte Themen