Ich folge der Spezifikation hier und bin mir nicht sicher, ob onFulfilled mit mehreren Argumenten aufgerufen werden kann. Zum Beispiel:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled('arg1', 'arg2');
})
so dass mein Code:
promise.then(function(arg1, arg2){
// ....
});
würde beide erhalten arg1
und arg2
?
Es ist mir egal, wie eine bestimmte Versprechungsimplementierung funktioniert, ich möchte die w3c-Spezifikation für Versprechungen genau befolgen.
Ich folge hier der Spezifikation und bin mir nicht sicher, ob onFulfilled mit mehreren Argumenten aufgerufen werden kann.
Nein, nur der erste Parameter wird im Versprechen-Konstruktor als Auflösungswert behandelt. Sie können mit einem zusammengesetzten Wert wie einem Objekt oder Array auflösen.
Es ist mir egal, wie eine bestimmte Versprechungsimplementierung funktioniert, ich möchte die w3c-Spezifikation für Versprechungen genau befolgen.
Ich glaube, du liegst falsch. Die Spezifikation ist so konzipiert, dass sie minimal ist und für die Interoperabilität zwischen Versprechen-Bibliotheken ausgelegt ist. Die Idee ist, eine Teilmenge zu haben, die beispielsweise DOM-Futures zuverlässig nutzen und Bibliotheken konsumieren können. Promise Implementierungen machen was Sie verlangen mit .spread
seit einiger Zeit. Zum Beispiel:
Promise.try(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c); // "Hello World!";
});
Mit Bluebird . Eine Lösung, wenn Sie diese Funktionalität wünschen, ist die Polyfüllung.
if (!Promise.prototype.spread) {
Promise.prototype.spread = function (fn) {
return this.then(function (args) {
return Promise.all(args); // wait for all
}).then(function(args){
//this is always undefined in A+ complaint, but just in case
return fn.apply(this, args);
});
};
}
So können Sie:
Promise.resolve(null).then(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c);
});
Mit einheimischen Versprechungen wohl Geige . Oder verwenden Sie die in Browsern heute (2018) übliche Verbreitung:
Promise.resolve(["Hello","World","!"]).then(([a,b,c]) => {
console.log(a,b+c);
});
Oder mit erwarten:
let [a, b, c] = await Promise.resolve(['hello', 'world', '!']);
Sie können die E6-Destrukturierung verwenden:
Objektdestrukturierung:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled({arg1: value1, arg2: value2});
})
promise.then(({arg1, arg2}) => {
// ....
});
Array destructuring:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled([value1, value2]);
})
promise.then(([arg1, arg2]) => {
// ....
});
Der Erfüllungswert eines Versprechens entspricht dem Rückgabewert einer Funktion, und der Ablehnungsgrund eines Versprechens entspricht der geworfenen Ausnahme einer Funktion. Funktionen können nicht mehrere Werte zurückgeben, daher dürfen Zusagen nicht mehr als 1 Erfüllungswert enthalten.
Soweit ich das Lesen der ES6 Promise-Spezifikation und der Standard-Promise-Spezifikation beurteilen kann, gibt es keine Klausel, die eine Implementierung daran hindert, diesen Fall zu behandeln - sie ist jedoch nicht in den folgenden Bibliotheken implementiert:
Ich gehe davon aus, dass der Grund für das Weglassen von Multi-Arg-Auflösungen darin besteht, die Reihenfolge prägnanter zu gestalten (d. H. Da Sie nur einen Wert in einer Funktion zurückgeben können, würde dies den Steuerungsfluss weniger intuitiv machen). Beispiel:
new Promise(function(resolve, reject) {
return resolve(5, 4);
})
.then(function(x,y) {
console.log(y);
return x; //we can only return 1 value here so the next then will only have 1 argument
})
.then(function(x,y) {
console.log(y);
});
Ich suche nach der gleichen Lösung und fand etwas sehr Interessantes aus dieser Antwort: Versprechen mit mehreren Argumenten (wie $ http) in AngularJS ablehnen
die Antwort dieses Kerls Florian
promise = deferred.promise
promise.success = (fn) ->
promise.then (data) ->
fn(data.payload, data.status, {additional: 42})
return promise
promise.error = (fn) ->
promise.then null, (err) ->
fn(err)
return promise
return promise
Und um es zu benutzen:
service.get().success (arg1, arg2, arg3) ->
# => arg1 is data.payload, arg2 is data.status, arg3 is the additional object
service.get().error (err) ->
# => err
Da Funktionen in Javascript mit einer beliebigen Anzahl von Argumenten aufgerufen werden können und das Dokument die Argumente der onFulfilled () -Methode abgesehen von der folgenden Klausel nicht einschränkt, können Sie meiner Meinung nach der onFulfilled () -Methode so lange mehrere Argumente übergeben als der Wert des Versprechens ist das erste Argument.
2.2.2.1 it must be called after promise is fulfilled, with promise’s value as its first argument.
Tolle Frage und tolle Antwort von Benjamin, Kris und anderen - vielen Dank!
Ich benutze dies in einem Projekt und habe ein Modul erstellt, das auf Benjamin Gruenwalds Code basiert. Es ist auf npmjs verfügbar:
npm i -S promise-spread
Dann machen Sie in Ihrem Code
require('promise-spread');
Wenn Sie eine Bibliothek wie any-promise
Verwenden
var Promise = require('any-promise');
require('promise-spread')(Promise);
Vielleicht finden das auch andere nützlich!
Um den folgenden Artikel in Anführungszeichen zu setzen, "" werden dann zwei Argumente verwendet, ein Rückruf für einen Erfolgsfall und ein anderes für den Fehlerfall. Beide sind optional, sodass Sie einen Rückruf nur für den Erfolgsfall oder den Fehlerfall hinzufügen können. "
Normalerweise schaue ich auf dieser Seite nach grundlegenden Versprechungsfragen. Lassen Sie mich wissen, wenn ich falsch liege