await on synchronous functions

Mark S. Miller erights at google.com
Fri Jul 17 22:10:55 UTC 2015


On Fri, Jul 17, 2015 at 12:57 PM, Ben Newman <benjamin at cs.stanford.edu>
wrote:

> Yep, all current implementations that I know of (Traceur,
> Babel/Regenerator, various other generator-based approaches) do what you
> want, because Promise.resolve(fn()).then(result => ...) always runs the
> callback a future turn of the event loop.
>
> Please note I might not be using the term "turn" precisely here
> (microtask?); my point is just that your example would not be blocking the
> event loop, and that's a good thing!


"task" and "microtask" are browser concepts, not JS concepts. The JS
concept is indeed what E calls a "turn", but the official EcmaScript
standards language for turn is "job". Please let's stick with "job".




>
> On Fri, Jul 17, 2015 at 12:50 PM Mark Volkmann <r.mark.volkmann at gmail.com>
> wrote:
>
>> Going back to my original question, suppose I write this:
>>
>> for (let fn of myFunctions) {
>>   let result = await fn();
>>   // Do something with result.
>> }
>>
>> If all the functions happen to be synchronous and take a while to
>> complete, am I blocking the event loop?
>> I think what I'd like to happen is for each call to happen in the next
>> pass through the event loop.
>>
>> On Fri, Jul 17, 2015 at 2:44 PM, Ben Newman <benjamin at cs.stanford.edu>
>> wrote:
>>
>>> Having addressed (1) earlier, perhaps by mistake, my thought on (2) is
>>> that you probably want await f() to work the same way if f() just happens
>>> to return a Promise, as when f is actually async, but there is no way to
>>> know, in general, if some arbitrary function will or will not return a
>>> Promise, so await should treat all arguments in the same way: by calling
>>> Promise.resolve.
>>>
>>> It's an open question whether a sufficiently smart runtime could
>>> optimize cases when the argument is not a Promise, or when the Promise is
>>> already resolved, but it would have to do so under the constraint of not
>>> revealing that optimization to the user.
>>>
>>> On Fri, Jul 17, 2015 at 12:36 PM Chris Toshok <toshok at gmail.com> wrote:
>>>
>>>> I think we're confusing two different cases here:
>>>>
>>>> 1) usage of `await` in the body of a function that is not itself marked
>>>> as `async`
>>>> 2) usage of `await f()` where `f` is not marked as `async`.
>>>>
>>>> 1 is easy to mark as an early error (and should be imo).  2, not so
>>>> much (and is what Mark was asking?)
>>>>
>>>> -c
>>>>
>>>>
>>>> On Fri, Jul 17, 2015 at 12:30 PM, Ben Newman <benjamin at cs.stanford.edu>
>>>> wrote:
>>>>
>>>>> If we stick with the rule that await is only regarded as a keyword if
>>>>> it appears in the body of an async function, then await x without async is
>>>>> simply a syntax error, and we can avoid having to answer this question!
>>>>>
>>>>> That said, perhaps a more natural way of handling wayward await
>>>>> expressions is to treat them as referring to the closest enclosing async
>>>>> function on the call stack (not necessarily the immediate enclosing
>>>>> function), throwing an exception if there is no async function on the
>>>>> stack. Then any await expression would delay the resolution of the Promise
>>>>> returned by whatever async function is currently executing. The
>>>>> same-function-body syntax restriction is a special case of that more
>>>>> general model (and notably easier to implement by transpiling to
>>>>> generators!).
>>>>>
>>>>> Generalizing async/await in this way turns out to be equivalent to
>>>>> introducing coroutines into the language, and while I would love to see
>>>>> that happen one day (it would greatly simplify writing parallel forEach
>>>>> loops, for example), it would require substantial changes to the execution
>>>>> model of the language.
>>>>>
>>>>> Here are some slides from a talk I gave earlier this year about the
>>>>> benefits and pitfalls of coroutines, in case you're interested:
>>>>> http://benjamn.github.io/goto2015-talk
>>>>> On Fri, Jul 17, 2015 at 11:35 AM Andrea Giammarchi <
>>>>> andrea.giammarchi at gmail.com> wrote:
>>>>>
>>>>>> > Think about a large program where you refactor a single async
>>>>>> function to no longer be async
>>>>>>
>>>>>> did that ever happened in the history of logic? I am actually curious
>>>>>> to understand a single valid case where that would be a solution to any
>>>>>> problem.
>>>>>>
>>>>>> Apologies if I can't see your point but we've been talking about
>>>>>> "Promise must Promise" so much this answer was absolutely unexpected.
>>>>>>
>>>>>> Thanks for any sort of clarification
>>>>>>
>>>>>> On Fri, Jul 17, 2015 at 7:27 PM, Tom Van Cutsem <tomvc.be at gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> 2015-07-17 19:41 GMT+02:00 Andrea Giammarchi <
>>>>>>> andrea.giammarchi at gmail.com>:
>>>>>>>
>>>>>>>> If I might, if there's one thing that has never particularly shone
>>>>>>>> in JS, that is consistency.
>>>>>>>>
>>>>>>>> I see only two possibilities here: 1) it throws with non Promises
>>>>>>>> 2) it "Promisify" anything that's not a Promise as if it was a
>>>>>>>> `Promise.resolve(1)` ... but since there's too much magic in the second
>>>>>>>> point, I'd rather stick with the first one.
>>>>>>>>
>>>>>>>
>>>>>>> I would be highly in favor of (2). Think about a large program where
>>>>>>> you refactor a single async function to no longer be async. Then I see no
>>>>>>> reason why I should be forced to refactor all of its callers to remove the
>>>>>>> await keyword. Going from sync to async requires refactoring because you're
>>>>>>> introducing new potential interleaving hazards, but any code that is
>>>>>>> already prepared to work with async functions (or promises in general)
>>>>>>> should work equally fine on immediately resolved promises.
>>>>>>>
>>>>>>> regards,
>>>>>>> Tom
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> Just my quick thoughts
>>>>>>>>
>>>>>>>> Best Regards
>>>>>>>>
>>>>>>>> On Fri, Jul 17, 2015 at 6:33 PM, Kevin Smith <zenparsing at gmail.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> I know the spec for this isn't finalized, but what is the current
>>>>>>>>>> direction for the behaviour when await is used on a function that is not
>>>>>>>>>> marked async and doesn't return a Promise? Should it run immediately or
>>>>>>>>>> wait for the next turn of the event loop?
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> More generally, the question is: what should await do for
>>>>>>>>> non-promises?
>>>>>>>>>
>>>>>>>>>     await 1;
>>>>>>>>>
>>>>>>>>> Should it force a job to be queued?
>>>>>>>>>
>>>>>>>>> _______________________________________________
>>>>>>>>> es-discuss mailing list
>>>>>>>>> es-discuss at mozilla.org
>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> es-discuss mailing list
>>>>>>>> es-discuss at mozilla.org
>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>> _______________________________________________
>>>>>> es-discuss mailing list
>>>>>> es-discuss at mozilla.org
>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> es-discuss mailing list
>>>>> es-discuss at mozilla.org
>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>
>>>>>
>>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>>
>> --
>> R. Mark Volkmann
>> Object Computing, Inc.
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>


-- 
    Cheers,
    --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150717/872dd272/attachment-0001.html>


More information about the es-discuss mailing list