0

I've been looked on StackOverflow and haven't seen any direct examples of what I'm asking. I'm reading this article on memoization link here if you want to look.

It appears to me that you should be able to run them all together and use the return value from getSoupRecipe() as input for hireSoupChef()

async function makeSoupFromType(soupType) {
    
    let [ soupRecipe, soupPan, soupChef ] = await Promise.all([
        
        getSoupRecipe(soupType),
        buySoupPan(),
        hireSoupChef(soupRecipe.requiredSkills)
    ]);
    
    return await makeSoup(soupChef, soupRecipe, soupPan);
}

So the question is can all three async functions run at the same time and once getSoupRecipe returns I use it's variable name (which is soupRecipe) as input for hireSoupChef.

I would post all the other code here for you to see but I think it would probably make the question look too daunting, so the link is above. You don't necessarily have to look at it to understand I don't think because I think I've stated the question right, but nonetheless if you want to you can.

ArrSky76
  • 33
  • 4
  • 2
    `So the question is can all three async functions run at the same time and once getSoupRecipe returns I use it's variable name (which is soupRecipe) as input for hireSoupChef.` No, by definition one can't run __at the same time__ as another one if one requires the others result as input. Thats what chaining was made for – tkausl Nov 28 '20 at 22:28
  • Your question contains the answer: **run at the same time and once getSoupRecipe returns** -- it's NOT the same time. – Kosh Nov 28 '20 at 22:30
  • Does promise.all() not run them all together?, similar to how multi-threaded stuff works. And okay whether they're run *all* at the same time or not, can you do this. Can you use the return from one in the input of another in the context of Promise.all – ArrSky76 Nov 28 '20 at 22:33
  • Promise.all() runs them, but does not resolve/reject until all have resolved or one has rejected. – Randy Casburn Nov 28 '20 at 22:33
  • @RandyCasburn What would be the appropriate infrastructure? I'm not having a problem, more as a need for clarification of how it works – ArrSky76 Nov 28 '20 at 22:34
  • OK, next time please consider stating that purpose for the question. It would be helpful for shallow thinkers like me :-) Thanks for clarifying. – Randy Casburn Nov 28 '20 at 22:35
  • The appropriate infrastructure just meant that everything (we can't see) actually returns promises, but you don't really have an issue with the code working, so that doesn't apply anymore. – Randy Casburn Nov 28 '20 at 22:36
  • @RandyCasburn But can the resolving of one be used in another, say I wrote it with hireSoupChef(soupRecipe.requiredSkills) first then getSoupRecipe(soupType)... Would hireSoupChef sit around not knowing what to do, and then once getSoupRecipe is there, then hireSoupChef works. Especially because the variable that represents the return of getSoupType is outside of this scope isnt it (bc its not in the Promise.All) so was wondering if one could use that – ArrSky76 Nov 28 '20 at 22:37
  • 1
    As Bergi said, NO - it cannot. you've got to chain them. As I said, `Promise.All()` does not resolve _until they are all resolved_ OR _until one of them rejects_. So no, you cannot use one of the values prior to the others being available. – Randy Casburn Nov 28 '20 at 22:39
  • 1
    @RandyCasburn Oh okay, so because Promise.All() hasn't resolved yet that would mean it's variables [ soupRecipe, soupPan, soupChef ] have also not been set yet so even more so could never be used as inputs. Thanks for the clarification! – ArrSky76 Nov 28 '20 at 22:41
  • Yes, exactly! Glad to help. – Randy Casburn Nov 28 '20 at 22:42

1 Answers1

0

Not by itself, no. In your example the soupRecipe (and the other two variables) are only initialised after the Promise.all(…) has been awaited, so it can't be used in the expressions that are passed to Promise.all as an argument. There's no magic going on here, Promise.all is not part of the syntax but really just returning one promise that fulfills with an array once.

However, the approach outlined in this answer to How do I access previous promise results in a .then() chain? does enable the desired chaining of asynchronous actions:

async function makeSoupFromType(soupType) {
    const soupRecipePromise = getSoupRecipe(soupType);
    const [soupRecipe, soupPan, soupChef] = await Promise.all([
        soupRecipePromise,
        buySoupPan(),
        soupRecipePromise.then(({requiredSkills}) => hireSoupChef(requiredSkills))
    ]);
    
    return makeSoup(soupChef, soupRecipe, soupPan);
}

Alternatively, with plain async/await you could also use an IIFE to avoid the then() call:

async function makeSoupFromType(soupType) {
    const [soupPan, [soupRecipe, soupChef]] = await Promise.all([
        buySoupPan(),
        (async () => {
            const soupRecipe = await getSoupRecipe(soupType);
            const soupChef = await hireSoupChef(soupRecipe.requiredSkills);
            return [soupRecipe, soupChef];
        })(),
    ]);
    
    return makeSoup(soupChef, soupRecipe, soupPan);
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • so Promise.all() runs concurrently, meaning they all run at once right (?), it's just the variables aren't initalised until the whole thing returns – ArrSky76 Nov 28 '20 at 22:49
  • @ArrSky76 No, running them concurrently (with `buySoupPan()`) is of course faster than running it sequentially after or before that. "*A couple other people commented saying they didn't run all at the same time*" - that's not what they said. What they said is that you don't *want* to run `getSoupRecipe` and `hireSoupChef` at the same time but rather sequentially (with the result of one being the input of the other), which is why your original `Promise.all` code doesn't work. – Bergi Nov 28 '20 at 22:55
  • Also, `Promise.all` doesn't "run" anything. What's starting the actions are the calls to `buySoupPan()` and `getSoupRecipe()`, which both happen immediately, causing the asynchronous tasks to run concurrently. What `Promise.all` does is only to wait for all results of the promises created before. – Bergi Nov 28 '20 at 22:57
  • Thanks this makes sense – ArrSky76 Nov 28 '20 at 23:06