Skip to content

johnhenry/asynchronous-blocks

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

Asynchronous Blocks

ECMAScript proposal, specs, tests, and reference implementation for Asynchronous locks

This initial proposal was drafted by @johnhenry with input from @_ and @_.

Designated TC39 reviewers: @_ @_

Table of Contents

Status

This proposal is currently at stage 0 of the process.

Prior Art

Some of the syntaxes in this proposal, namely the "do await" syntax, have been discussed before

Rationale and Motivation

Previously, in order to preform a one-off task within a program that didn't affect the global scope, one had to use an Immediately Invoked Function Expression (IIFE).

(function(){
  const a = 1;
  console.log(a);
  //other stuff...
})();
(function(){
  const a = 2;
  console.log(a);
  //other stuff...
})();
//logs "1", "2";

With blocks and blocked scoped variables, introduced for 2015, the syntax becomes much cleaner.

{
  const a = 1;
  console.log(a);
  //other stuff
}
{
  const a = 2;
  console.log(a);
  //other stuff
}
console.log(a);
//logs "1", "2";

Currently if we want to invoke as asynchronous expression, set to be introduced for 2017 we must resort to using an IIFE once more.

(async function(){
  const a = await eventually(1);
  //other stuff...
})();
(async function(){
  const a = await eventually(2);
  //other stuff...
})();
//logs eventually "1", "2" or "2", "1"

Alternatively, we can use non-anoymous functions and invoke them later in the program:

const main = async function(){
  const a = await eventually(1);
  //other stuff...
};
const main2 = async function(){
  const a = await eventually(2);
  //other stuff...
}
main();
main2();
//logs eventually "1", "2" or "2", "1"

but this is still not as elegant as one might hope.

Proposed Solution: Asynchronous Blocks

We can make this cleaner by implementing asynchronous blocks

async {
  const a = await eventually(1);
  console.log(a);
  //other stuff
}
async {
  const a = await eventually(2);
  console.log(a);
  //other stuff
}
//logs eventually  "1", "2" or "2", "1"

Asynchronous blocks are executed asynchronously with respect to the surrounding context and allow use of the "await" keyword without having to create another functional scope.

other operators

This would work in conjunctions with other operators that come before blocks:

####for/for-in/for-of

const for(const i of [1, 2]) async {
  await eventually(i);
}
console.log(0);
//logs "0"
//logs eventually "1", "2"

for-await-of

See Asynchronous Iterator Proposal

async {
  for await(const i of eventuallyIterator(1, 2)) async{
    console.log(i);
  }
  console.log(0);
}
//logs "0"
//logs eventually "1", "2"

while

while(true) async {
  await eventually(i++);
}
console.log(0);
//logs "0"
//logs eventually "1", "2"...

do

See Do-Expression Proposal

const result = do async{
 const a = 1;
}
result.then(console.log.bind(console));
//logs eventually  "1"

Asynchronous blocks

When Number.prototype[Symbol.iterator] is called, the following steps are taken:

  • While parsing, if the keyword "async" is encountered directly before a block, execute that block's contents asynchronously with respect to the surrounding program.
  • That block will now have the "await" keyword available at the top level.
  • Declarations using keywords "let" and "const" would not affect the scope outside of the asynchronous block.
  • Keeping in mind backward compatibility, declarations using the keyword "var", along with naked declarations, would affect the scope outside of the asynchronous block.

transformation

The following transformation recursively on a string:

const match = /^async\s*{\s*(.*)\s*}/m;
const wrap = (code) => `(async function(){${code}})()`;
export default (code)=>{
  return match.test(code) ? wrap(code.match(match)[1]) : code;
};

would have the following result:

async { ... } -> (async function(){ ... })()

Although, it misses the requirement regarding "backward compatibility" above in that it does not respect the use of the "var" keyword.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published