Я следую спецификации здесь и не уверен, позволяет ли она вызывать onFulfilled с несколькими аргументами.
Нет, только первый параметр будет рассматриваться как значение разрешения в конструкторе обещания. Вы можете разрешить с помощью составного значения, такого как объект или массив.
Меня не волнует, как это работает какая-либо конкретная реализация обещаний, я хочу внимательно следить за спецификацией обещаний w3c.
Вот где я считаю, что вы ошибаетесь. Спецификация разработана так, чтобы быть минимальной и рассчитана на взаимодействие между библиотеками обещаний. Идея состоит в том, чтобы иметь подмножество, которое, например, фьючерсы 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);
});
С родными обещаниями спокойно возиться . Или используйте распространение, которое сейчас (2018) обычное дело в браузерах:
Promise.resolve(["Hello","World","!"]).then(([a,b,c]) => {
console.log(a,b+c);
});
Или с ожиданием:
let [a, b, c] = await Promise.resolve(['hello', 'world', '!']);