await on synchronous functions

Alexander Jones alex at weej.com
Wed Aug 5 08:34:24 UTC 2015


Promises may reasonably resolve with `undefined` so I don't see good reason
to special-case it.

I remain of the opinion that this is a simple type issue. You can't just
take a function returning number and change it to return array-of-number
and expect things to work, without refactoring the call sites.

Alex

On Wednesday, 5 August 2015, Tom Van Cutsem <tomvc.be at gmail.com> wrote:

> 2015-07-27 5:42 GMT+02:00 Dean Landolt <dean at deanlandolt.com
> <javascript:_e(%7B%7D,'cvml','dean at deanlandolt.com');>>:
>
>>
>> On Sun, Jul 26, 2015 at 8:07 AM, Benjamin Gruenbaum <benjamingr at gmail.com
>> <javascript:_e(%7B%7D,'cvml','benjamingr at gmail.com');>> wrote:
>>
>>> > Out of curiosity, can you give an example of the Not Good parts? ISTM
>>> the await prefix is more of an explicit cast than an implicit conversation,
>>> and other than the very small timing gap in how throws are handled I
>>> pointed out a few days ago, I can't think of any situations where a throw
>>> would make more sense than casting values to promises.
>>>
>>> Sure, lots of such cases exist today with promises and are easy to
>>> reproduce
>>>
>>> ```js
>>> async function foo {
>>>     let result = await bar; // instead of bar();
>>>     let result2 = await callbackFn(); // await on function that was not
>>> "promisified yet", that is, it takes a callback
>>>     let result3 = await [p1, p2, p3]; // people might expect a
>>> Promise.all on an array, but this doesn't actually wait for anything.
>>> }
>>> ```
>>>
>>
>> The first example is a basic type error, not at all specific to promises
>> or async programming -- it could be made any number of ways. If you want to
>> call it a footgun, that's fine -- but ISTM the only real solution is "use
>> TypeScript" (or some analog).
>>
>> I don't see how the last example could possibly exist today as it
>> reflects a hypothetical user's misunderstanding of `async/await` syntax
>> specifically. Perhaps there's a case to be made that there's a footgun here
>> (though I'd disagree), but it's beside the point of this thread.
>>
>
> I recently found out that a popular async cflow library for node based on
> generators, co <https://github.com/tj/co> does allow one to "await"
> (yield) an array, with the semantics that Benjamin alluded to (Promise.all
> synchronization). At least it indicates that this is not a totally
> unrealistic expectation on behalf of users. Personally I think
> automatically Promise.all'ing arrays is a bit too implicit, but I can
> understand why people find it appealing.
>
>
>> But the second example, `await callbackFn()`, seems reasonable. I still
>> think it would be a shame to punt on otherwise elegant ergonomics just due
>> to this, but I buy that there's at least some benefit now.
>>
>
> Speaking from experience with a programming language I was involved with
> called AmbientTalk, which has JS-style Promises, we did run into this issue
> and we had a pragmatic way of solving it. Translated into the context of
> this discussion, what we specified is that `await undefined` would raise a
> runtime error, while `await any-non-promise-value` would coerce the
> non-promise value into a resolved promise and await that promise instead.
>
> At first sight, it might feel awkward for `await` to special-case
> `undefined`, but given that it is JS's implicit return value, I suspect it
> would catch a lot of errors of the type Benjamin described above. It's a
> pragmatic way of dodging the footgun without completely breaking the
> symmetry between await and Promise.resolve.
>
> Cheers,
> Tom
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150805/4f166dec/attachment.html>


More information about the es-discuss mailing list