我正在遵循规范here,我不确定它是否允许使用多个参数调用onFulfilled。例如:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled('arg1', 'arg2');
})
这样我的代码:
promise.then(function(arg1, arg2){
// ....
});
会同时收到arg1
和arg2
吗?
我不关心任何特定的承诺如何实现它,我希望密切关注w3c规范的承诺。
答案 0 :(得分:118)
我在这里遵循规范,我不确定它是否允许使用多个参数调用onFulfilled。
不,只是第一个参数将被视为promise构造函数中的分辨率值。您可以使用复合值(如对象或数组)进行解析。
我不关心任何特定的承诺如何实现它,我希望密切关注w3c规范的承诺。
这就是我认为你错了。规范设计为最小,并且是为了在promise库之间进行互操作而构建的。我们的想法是拥有一个子集,例如DOM期货可以可靠地使用并且库可以消耗。承诺实现现在用.spread
执行您的问题。例如:
Promise.try(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c); // "Hello World!";
});
Bluebird。如果您想要此功能,一种解决方案是将其填充。
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);
});
};
}
这可以让你:
Promise.resolve(null).then(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c);
});
本地承诺轻松fiddle。或者在浏览器中使用现在(2018年)普及的传播:
Promise.resolve(["Hello","World","!"]).then(([a,b,c]) => {
console.log(a,b+c);
});
或等待:
let [a, b, c] = await Promise.resolve(['hello', 'world', '!']);
答案 1 :(得分:52)
您可以使用E6解构:
对象解构:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled({arg1: value1, arg2: value2});
})
promise.then(({arg1, arg2}) => {
// ....
});
数据解构:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled([value1, value2]);
})
promise.then(([arg1, arg2]) => {
// ....
});
答案 2 :(得分:15)
promise的履行值与函数的返回值相似,并且promise的拒绝原因与函数的抛出异常平行。函数不能返回多个值,因此promises的履行值不得超过1。
答案 3 :(得分:4)
据我所知,在阅读ES6 Promise specification和standard promise specification时,没有任何条款阻止实现处理此案例 - 但是它未在以下库中实现:
我认为他们省略多个arg解析的原因是为了使更改顺序更简洁(即,因为你只能在函数中返回一个值,这会使控制流不那么直观)例如:
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);
});
答案 4 :(得分:2)
我正在寻找相同的解决方案,并从这个答案中找到了很多东西:Rejecting promises with multiple arguments (like $http) in AngularJS
这个家伙的答案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
使用它:
service.get().success (arg1, arg2, arg3) ->
# => arg1 is data.payload, arg2 is data.status, arg3 is the additional object
service.get().error (err) ->
# => err
答案 5 :(得分:1)
ES6中的解构分配会有所帮助。例如:
let [arg1, arg2] = new Promise((resolve, reject) => {
resolve([argument1, argument2]);
});
答案 6 :(得分:0)
引用下面的文章,“”然后“接受两个参数,成功案例的回调,以及失败案例的另一个。两者都是可选的,因此您只能为成功或失败案例添加回调。”
我通常会在本页面查看任何基本的承诺问题,如果我错了,请告诉我
答案 7 :(得分:0)
由于Javascript中的函数可以使用任意数量的参数调用,并且除了下面的子句之外,文档对onFulfilled()方法的参数没有任何限制,我认为你可以传递多个只要promise的值是第一个参数,onFulfilled()方法的参数。
2.2.2.1 it must be called after promise is fulfilled, with promise’s value as its first argument.
答案 8 :(得分:0)
很好的问题,本杰明,克里斯等人给出了很好的答案 - 非常感谢!
我在项目中使用它并创建了一个基于Benjamin Gruenwald's code的模块。它可以在npmjs上找到:
npm i -S promise-spread
然后在您的代码中,执行
require('promise-spread');
如果您使用的是any-promise
var Promise = require('any-promise');
require('promise-spread')(Promise);
也许其他人也认为这很有用!