Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What happens with await inside a block param? #28

Open
samuelgoto opened this issue Nov 30, 2017 · 4 comments
Open

What happens with await inside a block param? #28

samuelgoto opened this issue Nov 30, 2017 · 4 comments

Comments

@samuelgoto
Copy link
Owner

samuelgoto commented Nov 30, 2017

@dherman writes:

async function readstuff (cfg) {
  let fileA = null;
  unless (cfg.skipA) {
    fileA = await cfg.fileA;
  }
  // ...
}

Are await allowed inside block params? If so, do they interrupt the execution of readstuff or unless?

@dherman
Copy link

dherman commented Nov 30, 2017

Thanks for capturing this, Sam! (BTW it's missing an async on the function declaration.) My reason for writing it up is that I think this is one of the trickier technical issues here, and I think it's really important. If people learn that control structures can't be used reliably because they break inside async functions, they'll just take away that control structures built with block params are unreliable.

(Basically in a bake-off between async functions and block params, async functions will win.)

@dherman
Copy link

dherman commented Nov 30, 2017

But I should also add that I think Ron's ideas on the call were promising -- maybe there are solutions involving protocols like the iterator protocol, where we could actually allow propagation of await (and similarly yield).

In general, I'm saying that we should aim to get as absolutely close to TCP as possible, or else risk the feature being too non-general and unreliable to succeed. But I think there's reason for optimism that that's solvable!

@dissimulate
Copy link

dissimulate commented Dec 5, 2017

I think it'd be unintuitive to have any behaviour other than interrupting both, looking at that code it's how I'd expect it to run. Disallowing await inside the block is an option I suppose, but I think that's a feature people would certainly find useful as per your example.

There's more to think about though:

async function one (cb) {
  const result = await thing();
  cb();
}

function two (cb) {
  cb();
}

async function three () {
  // blocks until the callback it called
  await one () {
    // you can now block three() here
    await thing();
  }

  // what happens now? you'd expect the block to execute asynchronously
  one () {
    // ...but then the above behaviour won't work here
    await thing();
  }

  two () {
    // ...and it does here
    await thing();
  }

  // this shouldn't execute until all three thing()'s are complete
  const result = await thing();
  return result;
}

three();

Perhaps functions have an implicit await when called in the block param format, the behaviour will be consistent and this code would run as expected.

@Sceat
Copy link

Sceat commented May 30, 2019

let's totally break javascript for the sake of sexyness

// base
one(async x => {
	await x
})

// block params
one async {
	::await
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants