JavaScript await by default instead of manually

2020-03-30 05:46发布

问题:

Async/await are really handy, but I want the opposite of their behavior. Instead of other functions continuing on unless I manually ask them to await a promise, I want functions to yield unless I manually specify that they continue running in parallel.

For instance, this code would print out 1 3 2:

function wait(ms) {
    return new Promise(r => setTimeout(r, ms));
}

async function a() {
    console.log("1");
    await wait(5000);
    console.log("2");
}

a();
console.log("3");

I want it to print out 1 2 3, with function a() not actually returning until I've waited 5 seconds and 2 has been printed. I'm making an extension that I'd prefer to be lightweight, so I'd rather not use 3rd party libraries.

Is there any way to do this?

回答1:

Implicit await is bad, for reasons covered well in this blog. In short, consider why there's no need for locking in JavaScript. It's because we don't worry about being pre-empted willy-nilly.

Also, as mentioned by Daniel in comments, global await is not allowed either, presumably for backwards compatibility.

You can work around this by wrapping your top-level code like this:

let wait = ms => new Promise(r => setTimeout(r, ms));

async function a() {
  console.log("1");
  await wait(5000);
  console.log("2");
}

(async () => {

  // Put your top level code here!

  await a();
  console.log("3");

})().catch(e => setTimeout(() => { throw e; }));

Not perfect, but gets the job done, without turning everything upside down.