Can promises have multiple arguments to onFulfilled?
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'm following the spec here and I'm not sure whether it allows onFulfilled to be called with multiple arguments.
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 withI don't care about how any specific promises implementation does it, I wish to follow the w3c spec for promises closely.
.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 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: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', '!']);
Resolving a promise to multiple parameter values
No, the Promises spec only defines the first parameter. You can't pass in others, you can only emulate it using destructuring or spreads.
From the Promises/A+ spec, 2.2.2.1, emphasis mine:
IfThe ES6 spec describes this in NewPromiseReactionJob (27.2.2.1) step 1.e:onFulfilled
is a function:
- it must be called after
promise
is fulfilled, withpromise
’s value as its first argument.
e. Else, let handlerResult be Completion(HostCallJobCallback(handler, undefined, « argument »)).In both cases the spec allows a single Promise handler value. Unlike features like
setTimeout
where additional arguments can be passed to the handler, there is no such option for Promises.You can at least avoid repeating the argument list with spread syntax:
Promise.resolve()
.then(providesThreeValues)
.then(threeValues => takesThreeParameters(...threeValues))
.then(console.log);
Likewise, if you are willing to edit the function, the edit to takesThreeParameters
could be minimal with array destructuring:function takesThreeParameters ([a, b, c]) { // new brackets
console.log(`${a} ${b} ${c}`);
return 'something';
}
How do you properly return multiple values from a Promise?
You can't resolve a promise with multiple properties just like you can't return multiple values from a function. A promise conceptually represents a value over time so while you can represent composite values you can't put multiple values in a promise.
A promise inherently resolves with a single value - this is part of how Q works, how the Promises/A+ spec works and how the abstraction works.
The closest you can get is use Q.spread
and return arrays or use ES6 destructuring if it's supported or you're willing to use a transpilation tool like BabelJS.
As for passing context down a promise chain please refer to Bergi's excellent canonical on that.
How to resolve JS Promises with multiple values between parenthesis?
You can only send a single value, consider sending as an array and spreading it at the reciever
new Promise((resolve, reject) => {
return reject(new Error('no bears'));
setTimeout(() => {
resolve(['Bears', 'Lions', 'Tigers'])
}, 1000);
})
.then(quote => {
console.log(...quote); // spreads to 3 items
})
Resolve multiple promises within for loops before continuing
There is Promise.all to await multiple promises.
So what you need to do is to create an array of generateCanvasFromHtml()
executions from pdfComponents
and feed this array to Promise.all
.
Related Topics
How to Update a Specific Index from the Array in Firestore
Render Object Properties in React
Backbone: Why Assign '$('#Footer')' to 'El'
JavaScript Replace() Method Dollar Signs
How to Check "Checkbox" Dynamically - Jquery Mobile
JavaScript "Variable Variables": How to Assign Variable Based on Another Variable
How to Set Node_Env to Production/Development in Os X
Cross Domain Localstorage with JavaScript
Do Browsers Parse JavaScript on Every Page Load
How to Insert Variables in JavaScript Strings
How to Getting Browser Current Locale Preference Using JavaScript
How to Use Local Storage in Angular
How to Reset the Scale/Zoom of a Web App on an Orientation Change on the Iphone
How to Sign into Google with Selenium Automation Because of "This Browser or App May Not Be Secure."
How to Parse a Date in Format "Yyyymmdd" in JavaScript
How to Sort an Associative Array by Its Values in JavaScript