badunk badunk - 1 month ago 6
Javascript Question

Can promises have multiple arguments to onFulfilled?

I'm following the spec here and I'm not sure whether it allows onFulfilled to be called with multiple arguments. For example:

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


such that my code:

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


would receive both
arg1
and
arg2
?

I don't care about how any specific promises implementation does it, I wish to follow the w3c spec for promises closely.

Answer

I'm following the spec here and I'm not sure whether it allows onFulfilled to be called with multiple arguments.

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.

I don't care about how any specific promises implementation does it, I wish to follow the w3c spec for promises closely.

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:

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 pollyfill 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); 
        });

    };

}

Which 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.