Reflection to know if executed within a generator/async ?

Bradley Meck bradley.meck at gmail.com
Fri Dec 4 13:59:22 UTC 2015


The more I read about this the more I think that `await` is what you want
to change *not the behavior of functions*. Rephrased to what I think is
being asked:

If `await` encounters a non-thenable value, `Promise.resolve` the value
before awaiting.

Isn't this already the case?

On Fri, Dec 4, 2015 at 2:44 AM, Andrea Giammarchi <
andrea.giammarchi at gmail.com> wrote:

> Jordan please let's avoid discussions about migration patterns, I'm sure
> we've all done that and we all know how to. This is not the point of my
> idea.
>
> Claude, again, you are using promises already so you won't need this
> "magic".  Your API returns promises,  you are good to update to async/await
> or generators.
>
> However, in the future you won't write promises directly if not as
> returning values within some method .... right ?
>
> Looking at your code, I would always go for the second pattern instead of
> the first one. So what if you'd like to use that already, simply adding
> async and await and the only change to do in a well known/used
> *synchronous* API would be to check if the returned value is held and
> behave accordingly?
>
> That would give you a way to easily migrate to non-blocking as API
> consumer, and an easy way as API author to update to a non blocking version
> without breaking compatibility with other consumers.
>
> In this scenario,  you are still free to use `Promise.resolve(
> fileGetContent("foo"))` which not on hold and not concretely asynchronous
> in terms of `fileGetContent("foo")` operations, but as soon as you go for
> async/await or a generator that function will return a Promise for you.
>
> I hope it's clear now what is my idea.
>
> Regards
>
>
>
>
> On Fri, Dec 4, 2015 at 6:41 AM, Claude Pache <claude.pache at gmail.com>
> wrote:
>
>>
>> Le 3 déc. 2015 à 22:07, Andrea Giammarchi <andrea.giammarchi at gmail.com>
>> a écrit :
>>
>> Sorry I misread your code. Your case assumes fileGetContent always
>> returns a Promise so my proposal won't be useful there because it's already
>> used as Promise.
>>
>>
>> You can remove that assumption by replacing `fileGetContent("foo")` with
>> `Promise.resolve(fileGetContent("foo"))`.
>>
>>
>> My idea is more about migrating to full async code without changing all
>> the things around, giving an API the ability to behave differently.
>>
>>
>> The key fact of my example is that I can (and do) write full async code
>> without generators or async functions (just with ES3 + Promise), and you
>> have no way to detect that.
>> For example, the following code:
>>
>> ```js
>> function bar() {
>>     return Promise.resolve(fileGetContent("foo")).then(function (c) {
>>         // whatever
>>     })
>> }
>> ```
>>
>> is functionally equivalent to:
>>
>> ```js
>> async function bar() {
>>     const c = await fileGetContent("foo")
>>     // whatever
>> }
>> ```
>>
>> In both cases, I can receive a value or a promise for a value, and in
>> both cases getting a promise is strictly better.
>> I don't want to be served an inferior version of `fileGetContent` in the
>> first case just because you were unable to guess my intentions,
>> and I won’t hurry to migrate my existing code to use the second pattern,
>> because the difference is only cosmetic.
>>
>> —Claude
>>
>>
>>
>>
>> Maybe it's too complicated or too magic to implement, that's OK anyway.
>>
>> On Thu, Dec 3, 2015 at 8:59 PM, Claude Pache <claude.pache at gmail.com>
>> wrote:
>>
>>>
>>> Le 3 déc. 2015 à 20:04, Andrea Giammarchi <andrea.giammarchi at gmail.com>
>>> a écrit :
>>>
>>> I guess `held` would be like an arrow function, "transparent" when it
>>> comes to held invokes (like context or arguments)
>>>
>>>
>>> ? Sorry, but I don't understand how that would help to answer my
>>> question.
>>>
>>> —Claude
>>>
>>>
>>> On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <claude.pache at gmail.com>
>>> wrote:
>>>
>>>> How would you detect that the following call to your `fileGetContent`
>>>> function should return a Promise?
>>>>
>>>> ```js
>>>> function oldSchool() {
>>>>     return fileGetContent("foo").then(function (c) {
>>>>         // ....
>>>>     })
>>>> }
>>>> ```
>>>>
>>>> —Claude
>>>>
>>>>
>>>> > Le 3 déc. 2015 à 13:15, Andrea Giammarchi <
>>>> andrea.giammarchi at gmail.com> a écrit :
>>>> >
>>>> > Hi there,
>>>> >   just writing down some thoughts about being able to understand if a
>>>> method/function has been  executed within a generator/async and is being
>>>> yielded/awaited.
>>>> >
>>>> > Rationale: API that would like to behave synchronously in some case,
>>>> returning Promises in other cases.
>>>> >
>>>> > Example:
>>>> >
>>>> > ```js
>>>> > function fileGetContent(fileName) {
>>>> >   // random example
>>>> >   if (held) {
>>>> >     return fetch(fileName).then((r)=>r.text());
>>>> >   } else {
>>>> >     var xhr = new XMLHttpRequest;
>>>> >     xhr.open('GET', fileName, false);
>>>> >     xhr.send(null);
>>>> >     return xhr.responseText;
>>>> >   }
>>>> > }
>>>> > ```
>>>> >
>>>> > Above example will virtually return always the same type and it could
>>>> work inside a generator or an  async function as long as it's being held.
>>>> >
>>>> > Does any of this make sense? Is it worth exploring this pattern?
>>>> >
>>>> > Thanks for any sort of thought.
>>>> >
>>>> > Best  Regards
>>>> >
>>>> >
>>>> >
>>>> >
>>>> > _______________________________________________
>>>> > 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151204/776bcf7d/attachment.html>


More information about the es-discuss mailing list