承诺可以在onFulfilled上有多个参数吗?

时间:2014-03-31 23:09:52

标签: javascript promise

我正在遵循规范here,我不确定它是否允许使用多个参数调用onFulfilled。例如:

promise = new Promise(function(onFulfilled, onRejected){
    onFulfilled('arg1', 'arg2');
})

这样我的代码:

promise.then(function(arg1, arg2){
    // ....
});

会同时收到arg1arg2吗?

我不关心任何特定的承诺如何实现它,我希望密切关注w3c规范的承诺。

9 个答案:

答案 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 specificationstandard 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)

引用下面的文章,“”然后“接受两个参数,成功案例的回调,以及失败案例的另一个。两者都是可选的,因此您只能为成功或失败案例添加回调。”

我通常会在本页面查看任何基本的承诺问题,如果我错了,请告诉我

http://www.html5rocks.com/en/tutorials/es6/promises/

答案 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);

也许其他人也认为这很有用!