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

Isiah Meadows isiahmeadows at gmail.com
Wed Dec 6 19:35:37 UTC 2017


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