4 ms·
> (e.g. multiple concurrent calls via Q.all, multiple "returns" via callback arguments) How about: async function main () { try { const responses
by tanto 10y ago
> (e.g. multiple concurrent calls via Q.all, multiple "returns" via callback arguments)
How about:
async function main () {
try {
const responses = await Promise.all([
fetch('https://api.github.com/orgs/facebook'),
fetch('https://api.github.com/orgs/facebook')
]);
const jsons = await Promise.all(responses.map(res => res.json()))
} catch (err) {
console.log(err)
}
}
I think this is pretty clear and not needing any library for this is quite nice.
- dvlsg 10y agoJust to be picky, but I believe you would be better off with this: async function main () { try { const jsons = await Promise.all([ fetch('https://api.github.com/orgs/facebook'), fetch('https://api.github.com/orgs/facebook') ]).map(promise => promise.then(res => res.json())); } catch (err) { console.log(err) } } This way, if one response was much quicker than the other, you could begin sending it through the `res.json()` portion immediately, instead of waiting for both responses to return before continuing.
- coldtea 10y agoWould it? IIRC Promise.all will run the two responses in parallel, but will not send the first into the map before both are finished.
- awalGarg 10y agoPromise.all doesn't "run" anything. Promises "run" the very moment they come into existence. Promise.all simply tells you if and when all of them are settled. It depends on your Promises whether they are doing something outside the single threaded event loop or not for them to be parallel or not.
- girvo 10y ago> Promises "run" the very moment they come into existence Which is why I'm a massive fan of Futures from ramda-fantasy[0] instead of Promises for certain tasks! [0] https://github.com/ramda/ramda-fantasy/blob/master/docs/Future.md https://github.com/ramda/ramda-fantasy/blob/master/docs/Futu...
- coldtea 10y ago>Promise.all doesn't "run" anything. Promises "run" the very moment they come into existence. Yeah, I know that. I don't mean .all schedules them to run (e.g. like doing thread.start()), of course they auto start. By run I mean that inside the .all implementation syncs with you about their completion ("tells you when all of them are settled"). >It depends on your Promises whether they are doing something outside the single threaded event loop or not for them to be parallel or not. That's not the point though, which was the parent's assertion about whether the first to resolve will escape .all and go into the .map, which I don't think is the case.
- dvlsg 10y agoYes. They will be sent into map immediately, and Promise.all() will return a Promise which will settle when the mapped array is all settled (or one errors, but that's not really relevant to the question). We're really just awaiting the promise returned from Promise.all(), but mapping the original fetches into a "new" set of promises.
- jdgiese 10y agoI'm sorry, but I don't see why/how they would be sent to `map` immediately, given where the parenthesis are in the above code snippet. `Promise.prototype.map` isn't a builtin function is it? If the `map` call was inside the invocation of `Promise.all` then I could see it, but perhaps I am missing something.
- dvlsg 10y agoNo, you're right. That was a mistake on my part. The .map() should be called on the array, as calebegg pointed out.
- calebegg 10y agoNit -- you want: async function main () { try { const jsons = await Promise.all([ fetch('https://api.github.com/orgs/facebook'), fetch('https://api.github.com/orgs/facebook') ].map(promise => promise.then(res => res.json()))); } catch (err) { console.log(err) } } As written you get "Promise.all(...).map is not a function"
- ben_jones 10y agoJust to put it out there, an ES6 implementation using async.js would look like async.parallel({ facebook: done => request("https://api.github.com/orgs/facebook", done), twitter: done => request("https://api.github.com/orgs/twitter", done) }, (err, responses) => console.log(err, responses); ); And output something like: null, { facebook: { // facebook data }, twitter: { // twitter data } } Sure it suffers from a third party dependency and I would argue its slightly less concise, but we're getting to the point of opinionated API's just like some developers prefer promises, some will prefer async/await, others will continue with vanilla callbacks.
- esailija 10y agoThis is not the same at all. Any error in any of the callbacks is not catchable with one catch statement (you need separate try catch statement in every one of your callbacks). With async/await and promises, you only need one catch statement or one .catch method in one place because of proper error propagation and composition.
- ben_jones 10y agoHow common are dozens/hundreds of try-catch blocks in javascript code? Developers have long ago stopped caring about uncaught errors because it doesn't matter in the code they are writing, they catch every error they need to and leave the chips to fall where they may. In the same vein async.js will be catching all errors passed to done(err, response) and in the case of async.series() and similar calls, will stop the execution of concurrent actions as at the first error that is caught. Therefore I think its completely valid, because even though our examples are different, to most developers it doesn't even matter. I think you have a completely valid point, and it's probably a better world where we have proper error propagation and composition, just the reality of the situation is what it is.
- ej_campbell 10y agoYou should put the json parsing inside the Promise.all.
- andrewstuart2 10y agoI will admit that I hadn't realized async worked on Promises. This is definitely a very clean solution, though not one that can be seemingly achieved without Promise.all. There is, of course, no library needed to use pure promises for the same functionality, though. My point is that all of this is possible without async/await, which to me are abstractions that cloud the landscape, obscuring the real evented nature of JavaScript that makes async programming so easy, IMO.
- niagr 10y agoI'd say a bad programmer can produce shit regardless of the tools he is given. What async/await does is make complex async code much easier to read and maintain. Of course, you have all the expressive power of callbacks and promises at your disposal too. That's one of the great things about it. It's implemented on top of these constructs and they remain accessible.