Je suis la spécification ici et je ne suis pas sûr que cela permette à onFulfilled d'être appelé avec plusieurs arguments. Par exemple:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled('arg1', 'arg2');
})
tel que mon code:
promise.then(function(arg1, arg2){
// ....
});
recevrait à la fois arg1
et arg2
?
Peu m'importe la manière dont les promesses spécifiques sont mises en œuvre, je souhaite suivre de près les spécifications du W3C relatives aux promesses.
Je suis la spécification ici et je ne suis pas sûr que cela permette à onFulfilled d'être appelé avec plusieurs arguments.
Non, seul le premier paramètre sera traité comme une valeur de résolution dans le constructeur de la promesse. Vous pouvez résoudre avec une valeur composite telle qu'un objet ou un tableau.
Peu m'importe la manière dont les promesses spécifiques sont mises en œuvre, je souhaite suivre de près les spécifications du W3C relatives aux promesses.
C'est là que je crois que tu as tort. La spécification est conçue pour être minimale et est conçue pour l'interopérabilité des bibliothèques de promesses. L'idée est de disposer d'un sous-ensemble que les futurs DOM peuvent par exemple utiliser de manière fiable et que les bibliothèques peuvent consommer. Les implémentations de Promise font ce que vous demandez avec .spread
pendant un moment. Par exemple:
Promise.try(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c); // "Hello World!";
});
Avec Bluebird . Une solution si vous voulez cette fonctionnalité est de la polyfiller.
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);
});
};
}
Cela vous permet de faire:
Promise.resolve(null).then(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c);
});
Avec des promesses natales à l'aise violon . Ou utilisez la propagation qui est maintenant (2018) courante dans les navigateurs:
Promise.resolve(["Hello","World","!"]).then(([a,b,c]) => {
console.log(a,b+c);
});
Ou avec attendre:
let [a, b, c] = await Promise.resolve(['hello', 'world', '!']);
Vous pouvez utiliser la déstructuration E6:
déstructuration de l'objet:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled({arg1: value1, arg2: value2});
})
promise.then(({arg1, arg2}) => {
// ....
});
déstructuration du tableau:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled([value1, value2]);
})
promise.then(([arg1, arg2]) => {
// ....
});
La valeur d'exécution d'une promesse est parallèle à la valeur de retour d'une fonction et la raison de rejet d'une promesse est parallèle à l'exception levée d'une fonction. Les fonctions ne peuvent pas renvoyer plusieurs valeurs. Les promesses ne doivent pas avoir plus d'une valeur d'exécution.
Autant que je sache, les spécification de la promesse ES6 et la spécification de la promesse standard n'y a pas de clause empêchant une implémentation de gérer ce cas - cependant, elle n'est pas implémentée dans les bibliothèques suivantes:
Je suppose que la raison pour laquelle ils omettent la résolution de plusieurs arguments est de rendre l’ordre de changement plus succinct (c’est-à-dire que vous ne pouvez renvoyer qu’une valeur dans une fonction, le flux de contrôle deviendrait moins intuitif). Exemple:
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);
});
Je cherche la même solution et je trouve quelque chose de très intéressant dans cette réponse: Rejetant les promesses avec plusieurs arguments (comme $ http) dans AngularJS
la réponse de ce gars 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
Et pour l'utiliser:
service.get().success (arg1, arg2, arg3) ->
# => arg1 is data.payload, arg2 is data.status, arg3 is the additional object
service.get().error (err) ->
# => err
Puisque les fonctions en Javascript peuvent être appelées avec un nombre quelconque d'arguments, et que le document ne place aucune restriction sur les arguments de la méthode onFulfilled () en plus de la clause below, je pense que vous pouvez transmettre plusieurs arguments à la méthode onFulfilled () aussi longtemps comme la valeur de la promesse est le premier argument.
2.2.2.1 it must be called after promise is fulfilled, with promise’s value as its first argument.
Excellente question et excellente réponse de Benjamin, Kris et autres - merci beaucoup!
J'utilise cela dans un projet et j'ai créé un module basé sur code de Benjamin Gruenwald . Il est disponible sur npmjs:
npm i -S promise-spread
Puis dans votre code, faites
require('promise-spread');
Si vous utilisez une bibliothèque telle que any-promise
var Promise = require('any-promise');
require('promise-spread')(Promise);
Peut-être que d'autres trouvent cela utile aussi!
Pour citer l'article ci-dessous, "" then "prend deux arguments, un rappel pour un cas de réussite et un autre pour le cas d'échec. Les deux sont facultatifs, vous pouvez donc ajouter un rappel pour le cas de réussite ou d'échec uniquement."
Je regarde habituellement cette page pour des questions de base sur les promesses, laissez-moi savoir si je me trompe