it would be nice to have async-blocks like ``async {some_statements}`` and ``async (some_expression)``

Alan Johnson alan at breakrs.com
Tue Jan 3 15:55:55 UTC 2017


I’m all for the `async` block. In Scala, there actually are no `async` functions; only `async` blocks. (Technically, this isn’t in the language; it’s a macro from a library called scala-async <https://github.com/scala/async>.) This works out a bit more nicely because it’s expression-oriented to begin with.

But the nice thing about `async` blocks is that you can then use promise combinators within a function that might compose a couple different `async` operations. This might be a little less necessary in Javascript though, since it is rather flexible on the typing of promise-related functions; it will promote values to promises where necessary and flatten nested promises. Often in Scala, I’ll wrap a normal value in an `async` to make it a `Future` (Scala’s `Promise`).

> On Jan 3, 2017, at 10:48, Jeremy Martin <jmar777 at gmail.com> wrote:
> 
> That would create a refactoring hazard if i had the block: `{ a(); b(); return c(); }` and stuck the `async` keyword in front of it [...]
> 
> That's a pretty specific keyword to slip in before a given code block - is that really much of a real-world risk?
> 
> Also worth noting that the grammar here would have to preclude newlines between `async` and the opening bracket. This is already perfectly valid JavaScript:
> 
> var async = 'gotcha'
> 
> var promise = async
> 
> { console.log('hi!') }
> 
> That being said, this probably doesn't really make sense on it's own, but could definitely build on top of do/let blocks or lamdas (<-- not really current with the state of affairs on any of that).
> 
> 
> On Tue, Jan 3, 2017 at 10:16 AM, Jordan Harband <ljharb at gmail.com <mailto:ljharb at gmail.com>> wrote:
> That would create a refactoring hazard if i had the block: `{ a(); b(); return c(); }` and stuck the `async` keyword in front of it - suddenly the function wouldn't have an early completion in the block, it'd create and throw away a Promise.
> 
> On Tue, Jan 3, 2017 at 12:52 AM, Igor Baklan <io.baklan at gmail.com <mailto:io.baklan at gmail.com>> wrote:
> I looks like it would be nice to have ``async``-block which might be alias to ``async``-lambda immediate invocation, so that:
> 
> ```js
> var promise = async { /*some statements with await*/ };
> ```
> <==>
> 
> ```js
> var promise = (async () => { /*some statements with await*/ }) ();
> ```
> 
> and
> 
> ```js
> var promise = async ( /*some statements with await*/ );
> ```
> <==>
> 
> ```js
> var promise = (async () => ( /*some expression with await*/ )) ();
> ```
> 
> Then it can gave some convenience in writing some semi-async function, like for example parallel async batch processing, which might look like:
> 
> ```js
> const backupBatch = (batch) => {
>   var tasks = [];
>   for (let item of batch) {
>     tasks.push(
>       async {
>         const content = await readContent(item);
>         await writeContent(item + ".bak", content);
>       }
>     )
>   }
>   return Promise.all(tasks)
> }
> ```
> 
> or like
> 
> ```js
> const backupBatch = (batch) => {
>   var tasks = [];
>   for (let item of batch) {
>     tasks.push(
>       async (
>         await writeContent(item + ".bak", await readContent(item));
>       )
>     )
>   }
>   return Promise.all(tasks)
> }
> ```
> 
> of course this simplistic case can be rewritten without ``async``-block like:
> 
> ```js
> const backupBatch = (batch) => {
>   return Promise.all(
>     batch.map(
>       async (item) => (
>         await writeContent(item + ".bak", await readContent(item));
>       )
>     )
>   );
> }
> ```
> However I believe this not reduce usefulness of initial ``async``-block construction.
> 
> Also it should be mentioned that this idea "is't new", something very similar I saw in [[async-do]](/topic/support-syntax#content-5) comment.
> 
> And finally, if this construct will  be introduced, it will provide some nice symmetry - of whether you put async keyword in function header definition, or at the very beginning of its body, like:
> 
> ```js
> const asyncFunc = async (/*args*/) => {/*function body with await-s*/};
> ``` 
> <==>
> ```js
> const asyncFunc = (/*args*/) => { return async {/*function body with await-s*/} };
> ``` 
> <==>
> ```js
> const asyncFunc = (/*args*/) => ( async {/*function body with await-s*/} );
> ``` 
> 
> And
> ```js
> const asyncFunc = async (args) => (some_async_expression);
> ``` 
> <==>
> ```js
> const asyncFunc = (args) => async (some_async_expression);
> ``` 
> 
> By the way parentheses here is essential, since ``async x => x`` != ``async (x => x)``, cause first evaluates into async-function, while the second should be evaluated into completed promise which value is ``sync`` function ``(x => x)``.
> 
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss>
> 
> 
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss>
> 
> 
> 
> 
> -- 
> Jeremy Martin
> 661.312.3853
> http://devsmash.com <http://devsmash.com/>
> @jmar777
> _______________________________________________
> 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/20170103/e85141d6/attachment.html>


More information about the es-discuss mailing list