# Concurrent Async and Normal Await Evaluation Blocks

**URL:** <https://es.discourse.group/t/concurrent-async-and-normal-await-evaluation-blocks/827>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [June 25, 2021, 1:24am UTC](https://es.discourse.group/t/concurrent-async-and-normal-await-evaluation-blocks/827 "2021-06-25T01:24:11Z")\
**Posts on this page:** 1\
**Showing post:** 19

<div class="post-metadata">

**Author:** ![Clemdz](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/clemdz/32/813_2.png) [@Clemdz](https://es.discourse.group/u/Clemdz)\
**Post date:** [July 5, 2021, 4:55pm UTC](https://es.discourse.group/t/concurrent-async-and-normal-await-evaluation-blocks/827/19 "2021-07-05T16:55:12Z")

</div>

This is an interesting topic! :)

I've been thinking about it recently, and I'd like to give it a try too.

So if I understood correctly, there are actually two main features to be discussed here:

- having a non-blocking `await`-like syntax inside async functions
- having some syntactic sugar for grouping several promises to be handled at the same time

Both those features combined would allow us to create a nice `Promise.all` syntactic sugar, but those could be treated separately (and that's what I'm going for here).

## Non blocking `await`-like syntax

I really like the `async const myVar = myPromise()` syntax idea.

However, I would rather place the `async` keyword after the `=` sign, like this:

```javascript
const myVar = async myPromise();

```

This would have the following pros:

- The parallel with the `await` syntax would be greater:

- This would also allow to use this `async` syntax without having to declare variables, like:

```javascript
async function () {
  async updateDB( /*...*/ );
  async fetch( /*...*/ );
}

```

One could argue that in that case, we could simply write instead:

```javascript
async function () {
  updateDB( /*...*/ );
  fetch( /*...*/ );
}

```

But here is the big difference: using `async` when calling the promises would ensure that those promises have settled before the wrapping async function resolves.  
This is the important point here, so that the language does not become a spaghetti mess of aynsc-resolving variables. Every promises called using `async` have to settle before the return statement of the function gets executed.

Also, compared to the version without `async`, this keyword gives a nice little indication that the function that is called is actually a promise, and not a regular function call.

### Deshugared syntax

Taking the simple following code:

```javascript
async function () {
  const a = async getA();
  const b = async getB();
  /* ... */
  return a + b;
}

```

the desugared version would more or less looks like this:

```javascript
async function () {
  let a;
  const _aPromise = getA().then(value => a = value);
  let b;
  const _bPromise = getB().then(value => b = value);
  /* ... */
  await _aPromise;
  await _bPromise;
  return a + b;
}

```

However, in this desugar version, we have to use `let` instead of `const` for variable declaration. This would a limitation of the desugared version only, in the real implementation, using `const` for async variable declaration should be possible.

Also, when awaiting the resolved value, there is the question whether the variable should be set to `undefined`, or left undeclared. If the variable can be declared using const, it makes sense that it stays undeclared, as setting the value to `undefined` and then updating to the resolved value would not be coherent with the `const` declaration.

### Rewriting `Promise.all`

At this point, we can already recreate our `Promise.all` example:

```javascript
async function () {
  let a, b, c;
  // Await the settlement of every promise inside this async function
  await (async () => {
    // Using the async keyword, so that the three promise get executed in parallel
    a = async getA();
    b = async getB();
    c = async getC();
    // As we are using the async keyword for the promises above
    // we have to wait for them before leaving the async function
  })();
  // Here, we know for sure that a, b, and c have settled
  d(a, b, c.property);
}

```

We could also imagine more complex examples:

```javascript
// Same as before, but let's get `a` using the fetch api
async function () {
  let a, b, c;
  await (async () => {
    async (async () => {
      const response = await fetch("url");
      a = await response.json();
    })();
    b = async getB();
    c = async getC();
  })();
  d(a, b, c.property);
}

```

The problem here is that creating wrapper promises isn't really readable.  
Also, variables created inside the wrapper promises aren't accessible in the parent scope.  
About this second point, we could instead write:

```javascript
async function () {
  const { a, b, c } = await (async () => {
    const a = async (async () => {
      const response = await fetch("url");
      return await response.json();
    })();
    b = async getB();
    c = async getC();
    return { a, b, c };
  })();
  d(a, b, c.property);
}

```

This fixes the issues of variable access, but this is even more difficult to read!

## Grouping promises

Here comes the second point of the topic. It would be great to have a dedicated syntax to group `await` and `async` promise calls together.

This syntax would need:

1. to be short and readable
2. to have scope coherence and consistency with the language. It could either:

- create a new scope, and have a way to return / expose variables to the outside scope
- do not create a new scope, and any created variables are directly accessible in the current scope

The difficulty about this point is to find a good syntax that meet these two necessary conditions.

As you initialy proposed, we could use `{ }` to create `await` and `async` block.  
(Here I'm changing the meaning you originally gave them, so that their behavior is the same as their "keyword" version)

Here is the definition of the `await` block:

```javascript
await {
  /* ... */
}
// instead of
await (async () => {
  /* ... */
})();

```

and here is the definition of the `async` block:

```javascript
async {
  /* ... */
}
// instead of
async (async () => {
  /* ... */
})();

```

So if we take back our last example, it would become:

```javascript
async function () {
  let a, b, c;
  await {
    async {
      const response = await fetch("url");
      a = await response.json();
    };
    b = async getB();
    c = async getC();
  };
  d(a, b, c.property);
}

```

However, this solution feels incomplete, because we have to declare variables outside the blocks, using the `let` keyword.

### Other ideas ?

We could also go for various other syntax, like the following one which does not create a new scope, thus any created variable is accessible anywhere in the function scope:

```javascript
async function () {
  await.{
    async.{
      const response = await fetch("url");
      const a = await response.json();
    }
    const b = async getB();
    const c = async getC();
  }
  d(a, b, c.property);
}

```

However, the `.{ }` syntax is not used anywhere else in the language, and this looks quite weird.  
I'm still presenting this idea, in case of it can inspire someone for something better, but I would personally not go for this one :)

Here is a last idea:

```javascript
async function () {
  await (
    async (
      const response = await fetch("url");
      const a = await response.json();
    );
    const b = async getB();
    const c = async getC();
  );
  d(a, b, c.property);
}

```

Here, using parentheses makes it clear that we are not creating a new scope, and that the variables are accessible anywhere in the function.  
However, it looks quite strange too, as it is not something we can already do in the language. Like the previous idea, I do not quite like this solution, I'm just sharing it in case it appeals to someone!

## To conclude

The `async` keyword used as a non-blocking `await` keyword could be quite versatile and powerful, but it could also mess up the language by making it even more complex to understand. What do you think about it?

Also, such an `async` keyword would be quite limited if it does not come along with a way to group certain promises together, because creating wrapper async functions is quite heavy and difficult to read.

However, finding a great syntatic sugar for this is complicated.  
So if someone has some ideas, please share them! :)

(and more generally, please feel free to share your thoughts about all of this!)

---

_[View the full topic](https://es.discourse.group/t/concurrent-async-and-normal-await-evaluation-blocks/827)._
