I'm following the spec here and I'm not sure whether it allows onFulfilled to be called with multiple arguments. For example:
我在这里遵循规范,我不确定它是否允许用多个参数调用onfulfillment。例如:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled('arg1', 'arg2');
})
such that my code:
这样我的代码:
promise.then(function(arg1, arg2){
// ....
});
would receive both arg1
and arg2
?
会收到arg1和arg2吗?
I don't care about how any specific promises implementation does it, I wish to follow the w3c spec for promises closely.
我不关心任何具体的承诺实现是如何实现的,我希望密切遵循w3c规范的承诺。
8 个解决方案
#1
102
I'm following the spec here and I'm not sure whether it allows onFulfilled to be called with multiple arguments.
我在这里遵循规范,我不确定它是否允许用多个参数调用onfulfillment。
Nope, just the first parameter will be treated as resolution value in the promise constructor. You can resolve with a composite value like an object or array.
不,只是第一个参数将在promise构造函数中作为解析值处理。可以使用组合值(如对象或数组)进行解析。
I don't care about how any specific promises implementation does it, I wish to follow the w3c spec for promises closely.
我不关心任何具体的承诺实现是如何实现的,我希望密切遵循w3c规范的承诺。
That's where I believe you're wrong. The specification is designed to be minimal and is built for interoperating between promise libraries. The idea is to have a subset which DOM futures for example can reliably use and libraries can consume. Promise implementations do what you ask with .spread
for a while now. For example:
这就是我认为你错的地方。该规范被设计为最小的,并构建为承诺库之间的互操作。其思想是拥有一个子集,例如DOM期货可以可靠地使用,库可以使用。承诺实现现在就按照您的要求进行扩展。例如:
Promise.try(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c); // "Hello World!";
});
With Bluebird. One solution if you want this functionality is to polyfill it.
蓝知更鸟。如果您想要这个功能,一种解决方案是对它进行多边形填充。
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);
});
};
}
This lets you do:
这可以让你:
Promise.resolve(null).then(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c);
});
With native promises at ease fiddle. Or use spread which is now (2018) commonplace in browsers:
自然的承诺很轻松。或者使用现在(2018年)在浏览器中很常见的扩展:
Promise.resolve(["Hello","World","!"]).then(([a,b,c]) => {
console.log(a,b+c);
});
Or with await:
或者等待:
let [a, b, c] = await Promise.resolve(['hello', 'world', '!']);
#2
34
You can use E6 destructuring:
可以使用E6解构:
Object destructuring:
对象解构:
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]) => {
// ....
});
#3
14
The fulfillment value of a promise parallels the return value of a function and the rejection reason of a promise parallels the thrown exception of a function. Functions cannot return multiple values so promises must not have more than 1 fulfillment value.
承诺的实现价值与函数的返回值相同,而承诺的拒绝理由与函数抛出的异常相似。函数不能返回多个值,因此承诺必须不超过一个履行值。
#4
3
As far as I can tell reading the ES6 Promise specification and the standard promise specification theres no clause preventing an implementation from handling this case - however its not implemented in the following libraries:
据我所知,在阅读ES6承诺规范和标准承诺规范时,没有条款阻止实现处理这种情况——但是它没有在以下库中实现:
- RSVP.promise (#L516-544)
- 回复。承诺(# l516 - 544)
- Q promise (#787)
- 问承诺(# 787)
I assume the reason for them omiting multi arg resolves is to make changing order more succinct (i.e. as you can only return one value in a function it would make the control flow less intuitive) Example:
我认为,它们省略多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);
});
#5
2
I am looking for the same solution and found seomething very intersting from this answer: Rejecting promises with multiple arguments (like $http) in AngularJS
我正在寻找相同的解决方案,发现seomething与此答案非常相关:拒绝使用AngularJS中的多个参数(如$http)的承诺
the answer of this guy 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
And to use it:
和使用它:
service.get().success (arg1, arg2, arg3) ->
# => arg1 is data.payload, arg2 is data.status, arg3 is the additional object
service.get().error (err) ->
# => err
#6
0
To quote the article below, ""then" takes two arguments, a callback for a success case, and another for the failure case. Both are optional, so you can add a callback for the success or failure case only."
引用下面的文章,“then”接受两个参数,一个是成功案例的回调,另一个是失败案例的回调。两者都是可选的,所以您只能为成功或失败案例添加一个回调。
I usually look to this page for any basic promise questions, let me know if I am wrong
我通常在这一页寻找任何基本的承诺问题,如果我错了请告诉我
http://www.html5rocks.com/en/tutorials/es6/promises/
http://www.html5rocks.com/en/tutorials/es6/promises/
#7
0
Since functions in Javascript can be called with any number of arguments, and the document doesn't place any restriction on the onFulfilled() method's arguments besides the below clause, I think that you can pass multiple arguments to the onFulfilled() method as long as the promise's value is the first argument.
由于Javascript中的函数可以用任意数量的参数调用,而且除了下面的子句之外,文档对oncompleted()方法的参数没有任何限制,所以我认为只要承诺的值是第一个参数,就可以将多个参数传递给on成就感()方法。
2.2.2.1 it must be called after promise is fulfilled, with promise’s value as its first argument.
#8
0
Great question, and great answer by Benjamin, Kris, et al - many thanks!
很好的问题,本杰明,克里斯等人的回答,非常感谢!
I'm using this in a project and have created a module based on Benjamin Gruenwald's code. It's available on npmjs:
我在一个项目中使用它,并基于本杰明·格伦沃尔德的代码创建了一个模块。可以在npmjs:
npm i -S promise-spread
Then in your code, do
然后在你的代码中,做
require('promise-spread');
If you're using a library such as any-promise
如果您正在使用一个库,比如any-promise
var Promise = require('any-promise');
require('promise-spread')(Promise);
Maybe others find this useful, too!
也许其他人也觉得这很有用!
#1
102
I'm following the spec here and I'm not sure whether it allows onFulfilled to be called with multiple arguments.
我在这里遵循规范,我不确定它是否允许用多个参数调用onfulfillment。
Nope, just the first parameter will be treated as resolution value in the promise constructor. You can resolve with a composite value like an object or array.
不,只是第一个参数将在promise构造函数中作为解析值处理。可以使用组合值(如对象或数组)进行解析。
I don't care about how any specific promises implementation does it, I wish to follow the w3c spec for promises closely.
我不关心任何具体的承诺实现是如何实现的,我希望密切遵循w3c规范的承诺。
That's where I believe you're wrong. The specification is designed to be minimal and is built for interoperating between promise libraries. The idea is to have a subset which DOM futures for example can reliably use and libraries can consume. Promise implementations do what you ask with .spread
for a while now. For example:
这就是我认为你错的地方。该规范被设计为最小的,并构建为承诺库之间的互操作。其思想是拥有一个子集,例如DOM期货可以可靠地使用,库可以使用。承诺实现现在就按照您的要求进行扩展。例如:
Promise.try(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c); // "Hello World!";
});
With Bluebird. One solution if you want this functionality is to polyfill it.
蓝知更鸟。如果您想要这个功能,一种解决方案是对它进行多边形填充。
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);
});
};
}
This lets you do:
这可以让你:
Promise.resolve(null).then(function(){
return ["Hello","World","!"];
}).spread(function(a,b,c){
console.log(a,b+c);
});
With native promises at ease fiddle. Or use spread which is now (2018) commonplace in browsers:
自然的承诺很轻松。或者使用现在(2018年)在浏览器中很常见的扩展:
Promise.resolve(["Hello","World","!"]).then(([a,b,c]) => {
console.log(a,b+c);
});
Or with await:
或者等待:
let [a, b, c] = await Promise.resolve(['hello', 'world', '!']);
#2
34
You can use E6 destructuring:
可以使用E6解构:
Object destructuring:
对象解构:
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]) => {
// ....
});
#3
14
The fulfillment value of a promise parallels the return value of a function and the rejection reason of a promise parallels the thrown exception of a function. Functions cannot return multiple values so promises must not have more than 1 fulfillment value.
承诺的实现价值与函数的返回值相同,而承诺的拒绝理由与函数抛出的异常相似。函数不能返回多个值,因此承诺必须不超过一个履行值。
#4
3
As far as I can tell reading the ES6 Promise specification and the standard promise specification theres no clause preventing an implementation from handling this case - however its not implemented in the following libraries:
据我所知,在阅读ES6承诺规范和标准承诺规范时,没有条款阻止实现处理这种情况——但是它没有在以下库中实现:
- RSVP.promise (#L516-544)
- 回复。承诺(# l516 - 544)
- Q promise (#787)
- 问承诺(# 787)
I assume the reason for them omiting multi arg resolves is to make changing order more succinct (i.e. as you can only return one value in a function it would make the control flow less intuitive) Example:
我认为,它们省略多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);
});
#5
2
I am looking for the same solution and found seomething very intersting from this answer: Rejecting promises with multiple arguments (like $http) in AngularJS
我正在寻找相同的解决方案,发现seomething与此答案非常相关:拒绝使用AngularJS中的多个参数(如$http)的承诺
the answer of this guy 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
And to use it:
和使用它:
service.get().success (arg1, arg2, arg3) ->
# => arg1 is data.payload, arg2 is data.status, arg3 is the additional object
service.get().error (err) ->
# => err
#6
0
To quote the article below, ""then" takes two arguments, a callback for a success case, and another for the failure case. Both are optional, so you can add a callback for the success or failure case only."
引用下面的文章,“then”接受两个参数,一个是成功案例的回调,另一个是失败案例的回调。两者都是可选的,所以您只能为成功或失败案例添加一个回调。
I usually look to this page for any basic promise questions, let me know if I am wrong
我通常在这一页寻找任何基本的承诺问题,如果我错了请告诉我
http://www.html5rocks.com/en/tutorials/es6/promises/
http://www.html5rocks.com/en/tutorials/es6/promises/
#7
0
Since functions in Javascript can be called with any number of arguments, and the document doesn't place any restriction on the onFulfilled() method's arguments besides the below clause, I think that you can pass multiple arguments to the onFulfilled() method as long as the promise's value is the first argument.
由于Javascript中的函数可以用任意数量的参数调用,而且除了下面的子句之外,文档对oncompleted()方法的参数没有任何限制,所以我认为只要承诺的值是第一个参数,就可以将多个参数传递给on成就感()方法。
2.2.2.1 it must be called after promise is fulfilled, with promise’s value as its first argument.
#8
0
Great question, and great answer by Benjamin, Kris, et al - many thanks!
很好的问题,本杰明,克里斯等人的回答,非常感谢!
I'm using this in a project and have created a module based on Benjamin Gruenwald's code. It's available on npmjs:
我在一个项目中使用它,并基于本杰明·格伦沃尔德的代码创建了一个模块。可以在npmjs:
npm i -S promise-spread
Then in your code, do
然后在你的代码中,做
require('promise-spread');
If you're using a library such as any-promise
如果您正在使用一个库,比如any-promise
var Promise = require('any-promise');
require('promise-spread')(Promise);
Maybe others find this useful, too!
也许其他人也觉得这很有用!