async/await -> await/async: a simpler, less error-prone async syntax

kai zhu kaizhu256 at gmail.com
Thu Dec 7 07:35:07 UTC 2017


@isiah thx for link and read the article (i actually enjoy reading most of the links you post on this mailing list).

we can agree to disagree - i've been using recursive-callbacks for 5 years now. they’re quite powerful and elegantly solve the callback-hell issue.  recursive-callbacks can do pretty much anything you can do with async-await / generators / promises, are very easy to debug with breakpoints, and most importantly have no unobservable magic going on behind-the-scene.

> On Dec 7, 2017, at 2:35 AM, Isiah Meadows <isiahmeadows at gmail.com> wrote:
> 
> Kai, please read [this article][1]. Also, please stop filling your
> emails with walls of code - it makes it *much* easier to comprehend.
> If you feel the need to post pictures, please find an image hosting
> service or something. If you feel the need to show large amounts of
> code, please try using GH Gists, Pastebin, or similar. It just gets in
> the way of reading the emails, and not everyone can even see the
> images (notably if they aren't using an HTML-supporting client).
> 
> [1]: https://medium.freecodecamp.org/javascript-from-callbacks-to-async-await-1cc090ddad99?gi=170f198491b1
> -----
> 
> Isiah Meadows
> me at isiahmeadows.com
> 
> Looking for web consulting? Or a new website?
> Send me an email and we can get started.
> www.isiahmeadows.com
> 
> 
> On Tue, Dec 5, 2017 at 8:49 PM, kai zhu <kaizhu256 at gmail.com> wrote:
>> you can avoid this entire debate by using trusty and simple callbacks
>> instead.  here's real-world example of using a callback like you would
>> async/await, to asynchronously test various states/scenarios for user-login
>> in an app (using recursion to avoid callback-hell):
>> 
>> https://github.com/kaizhu256/node-swgg/blob/2017.7.24/test.js#L918
>> 
>> ```js
>> local.testCase_userLoginXxx_default = function (options, onError) {
>> /*
>> * this function will test userLoginXxx's default handling-behavior
>> */
>>    var modeNext, onNext;
>>    modeNext = 0;
>>    onNext = function (error, data) {
>>        modeNext += 1;
>>        switch (modeNext) {
>>        case 1:
>>            // cleanup userJwtEncrypted
>>            delete local.userJwtEncrypted;
>>            // test userLogout's default handling-behavior
>>            options = {};
>>            local.userLogout(options, onNext);
>>            break;
>>        case 2:
>>            // validate error occurred
>>            local.assert(error, error);
>>            // test userLoginByPassword's 401 handling-behavior
>>            options = { password: 'undefined', username: 'undefined' };
>>            local.userLoginByPassword(options, onNext);
>>            break;
>>        case 3:
>>            // validate error occurred
>>            local.assert(error, error);
>>            // validate statusCode
>>            local.assertJsonEqual(data.statusCode, 401);
>>            // validate userJwtEncrypted does not exist
>>            local.assert(!local.userJwtEncrypted, local.userJwtEncrypted);
>>            // test userLogout's 401 handling-behavior
>>            options = {};
>>            local.userLogout(options, onNext);
>>            break;
>>        case 4:
>>            // validate error occurred
>>            local.assert(error, error);
>>            // validate statusCode
>>            local.assertJsonEqual(data.statusCode, 401);
>>            // validate userJwtEncrypted does not exist
>>            local.assert(!local.userJwtEncrypted, local.userJwtEncrypted);
>>            // test userLoginByPassword's 200 handling-behavior
>>            options = { password: 'secret', username: 'admin' };
>>            local.userLoginByPassword(options, onNext);
>>            break;
>>        case 5:
>>            // validate no error occurred
>>            local.assert(!error, error);
>>            // validate statusCode
>>            local.assertJsonEqual(data.statusCode, 200);
>>            // validate userJwtEncrypted exists
>>            local.assert(local.userJwtEncrypted, local.userJwtEncrypted);
>>            // test persistent-session handling-behavior
>>            local.apiDict['x-test crudNullGet']._ajax({}, onNext);
>>            break;
>>        case 6:
>>            // validate no error occurred
>>            local.assert(!error, error);
>>            // validate statusCode
>>            local.assertJsonEqual(data.statusCode, 200);
>>            // validate userJwtEncrypted exists
>>            local.assert(local.userJwtEncrypted, local.userJwtEncrypted);
>>            // test userLogout's 200 handling-behavior
>>            // test jwtEncoded's update handling-behavior
>>            options = { jwtEncrypted: local.jwtA256GcmEncrypt({ sub: 'admin'
>> }) };
>>            local.userLogout(options, onNext);
>>            break;
>>        case 7:
>>            // validate no error occurred
>>            local.assert(!error, error);
>>            // validate statusCode
>>            local.assertJsonEqual(data.statusCode, 200);
>>            // validate userJwtEncrypted exists
>>            local.assert(local.userJwtEncrypted, local.userJwtEncrypted);
>>            // test userLogout's 401 handling-behavior
>>            options = {};
>>            local.userLogout(options, onNext);
>>            break;
>>        case 8:
>>            // validate error occurred
>>            local.assert(error, error);
>>            // validate statusCode
>>            local.assertJsonEqual(data.statusCode, 401);
>>            // test userLoginByPassword's 400 handling-behavior
>>            local.ajax({ url: '/api/v0/user/userLoginByPassword?password=1'
>> }, onNext);
>>            break;
>>        case 9:
>>            // validate error occurred
>>            local.assert(error, error);
>>            // validate statusCode
>>            local.assertJsonEqual(data.statusCode, 400);
>>            // test userLogout's invalid-username handling-behavior
>>            options = { jwtEncrypted: local.jwtA256GcmEncrypt({ sub:
>> 'undefined' }) };
>>            local.userLogout(options, onNext);
>>            break;
>>        case 10:
>>            // validate error occurred
>>            local.assert(error, error);
>>            // validate statusCode
>>            local.assertJsonEqual(data.statusCode, 401);
>>            onError(null, data);
>>            break;
>>        }
>>    };
>>    onNext();
>> };
>> ```
>> 
>> and here’s screenshot of setting a single-breakpoint to easily debug and
>> step through all 10 asynchronous switch-statements in the callback.
>> you can reproduce the test-case in screenshot with this link:
>> https://kaizhu256.github.io/node-swgg/build..beta..travis-ci.org/app/?modeTest=1&modeTestCase=testCase_userLoginXxx_default
>> 
>> -kai
>> 
>> 
>> 
>> On Dec 6, 2017, at 6:38 AM, Alexander Jones <alex at weej.com> wrote:
>> 
>>> with the added bonus of transparently allowing sync functions to be
>>> converted to async functions without fundamentally affecting consumer
>>> calling code.
>> 
>> It does fundamentally affect calling code if the calling code reaches
>> outside of its local variables. The state of the world around you might
>> change any time you await and give control back to the event loop.
>> 
>> On Mon, 4 Dec 2017 at 19:16, Naveen Chawla <naveen.chwl at gmail.com> wrote:
>>> 
>>> Obviously. The whole point of this proposal is that awaiting async
>>> functions is automatically _implied_ inside an `autoasync` function, unless
>>> an async function is called with a `background` qualifier (which thereby
>>> makes it return its promise instead). The OP is right: this is a far less
>>> bug prone way to do async programming than `async` `await`, while offering
>>> all its functionality, with the added bonus of transparently allowing sync
>>> functions to be converted to async functions without fundamentally affecting
>>> consumer calling code.
>>> 
>>> For those who want to be able to do extensive async programming, having
>>> this in the language, and using it instead of `await` `async` throughout, is
>>> a no-brainer.
>>> 
>>> Of course, I am qualifying that it must be new keywords, not `await`
>>> `async` juggled like in the original post, but that wasn't the thrust of the
>>> proposal anyway.
>>> 
>>> On Mon, 4 Dec 2017 at 21:09 Isiah Meadows <isiahmeadows at gmail.com> wrote:
>>>> 
>>>> Am I misunderstanding something about this proposal that it's
>>>> substantially any different from `.then` or immediately invoked async
>>>> functions?
>>>> 
>>>> ```js
>>>> // Original
>>>> await function foo() {
>>>>    const bar = async baz()
>>>>    use(bar)
>>>> }
>>>> 
>>>> // What I'm reading
>>>> function foo() {
>>>>    ;(async () => {
>>>>        const bar = await baz()
>>>>        use(bar)
>>>>    })()
>>>> }
>>>> function foo() {
>>>>    try {
>>>>        Promise.resolve(baz())
>>>>        .then(bar => { use(bar) })
>>>>    } catch (e) {
>>>>        Promise.reject(e)
>>>>    }
>>>> }
>>>> ```
>>>> 
>>>> 
>>>> On Mon, Dec 4, 2017, 09:54 T.J. Crowder <tj.crowder at farsightsoftware.com>
>>>> wrote:
>>>>> 
>>>>> On Mon, Dec 4, 2017 at 2:37 PM, Bob Myers <rtm at gol.com> wrote:
>>>>>> 
>>>>>> It turns out that this approach has a number of problems.
>>>>>> As a result, future versions of selenium will no longer support it.
>>>>>> Test writers will be asked to write `await` where needed.
>>>>> 
>>>>> Were there problems other than the complexity of maintaining the
>>>>> promise manager tool and issues with debuggability? Neither of those
>>>>> seems like it would be an issue with Steven's proposal...
>>>>> 
>>>>> (I just realized for the first time, Bob, that your initials are RTM.
>>>>> I love it. You should adopt Frank as a second middle name. ;-) )
>>>>> 
>>>>> -- T.J. Crowder
>>>>> _______________________________________________
>>>>> 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
>> 



More information about the es-discuss mailing list