Node: yield/await support in repl/cli

Created on 2 Sep 2016  路  31Comments  路  Source: nodejs/node

In the version of node 6.5.0 that I am running, the repl does support quite a few things already - which is awesome. One thing I came to miss when trying things out though is that the yield (as often used before await and/or the await keyword. If yield would be available like with co or await would be available like in the concept then async code would become easy to test in the REPL.

feature request help wanted repl

Most helpful comment

@Fishrock123 I think the idea is that the default repl wraps the code being run in a generator/async function so that the following works:

> var x = await Promise.resolve(1); x
1

~=

async () => {
  return eval(`var x = await Promise.resolve(1); x`);
}

await seems reasonable, particularly if modules get it at the top level, but not gonna bite on special casing yield.

All 31 comments

@martinheidegger It already is if you run a generator function, I'm not 100 sure what you are asking.
Could you provide an example?

@Fishrock123 I think the idea is that the default repl wraps the code being run in a generator/async function so that the following works:

> var x = await Promise.resolve(1); x
1

~=

async () => {
  return eval(`var x = await Promise.resolve(1); x`);
}

await seems reasonable, particularly if modules get it at the top level, but not gonna bite on special casing yield.

@Fishrock123 @bmeck Explained my request better than me.
@bmeck I am in agreement that await seems more reasonable, the only reason I mentioned yield is because async/await seemed like an unfinished feature at this point.

My personal example is working with nodegit

> var git = require('nodegit')
undefined
> var repo = await git.getRepo('.')
undefined
> await repo.getCommit(sha)
Commit { repo: Repository {} }

@martinheidegger async/await functions were accepted in July : https://github.com/tc39/proposals/blob/master/finished-proposals.md

+1 for such a feature. It would make it much easier to work with Promise-based APIs

blocked on v8 giving us unflagged async/await functions at the very least.

ref: https://bugs.chromium.org/p/v8/issues/detail?id=4483

I wonder if a --require module could appropriately extend the built-in repl?

@Fishrock123 well modules have not fully landed top level await in spec (proposal in september?) so the module parser in v8 won't land the await outside of async functions for a while still.

I mean for yield.

This is how I implemented in my electron based REPL.

const awaitMatcher = /^(?:\s*(?:(?:let|var|const)\s)?\s*([^=]+)=\s*|^\s*)(await\s[\s\S]*)/;
const asyncWrapper = (code, binder) => {
  let assign = binder ? `root.${binder} = ` : '';
  return `(function(){ async function _wrap() { return ${assign}${code} } return _wrap();})()`;
};

// match & transform
const match = input.match(awaitMatcher);
if(match) {
  input = `${asyncWrapper(match[2], match[1])}`;
}

little workaround / hack:

await=promise=>{
  ret = undefined
  promise.then(response=>ret=response)
  while(ret === undefined) {require('deasync').runLoopOnce();}
  return ret
}

or

await=async function(promise){
  result=await promise // result now available via side effect (workaround)
  return result // still PROMISE in return!??! but ok otherwise 
}

or just
await=promise=>promise.then(x=>result=x)

of course the proposed addition of await to the REPL would be way better!

@princejwesley how can I add your implementation to node repl?

I saw this as well: https://github.com/paulserraino/babel-repl

but it does not support await syntax yet

cc @paulserraino

@martinheidegger what is the link for your personal working example of here: https://github.com/nodejs/node/issues/8382#issuecomment-244389612

@sibelius Something like this

@sibelius Oh: I am afraid this is a misunderstanding: this is an example of how i _would love it to work_.

@princejwesley it does work tks for the awesome work

@martinheidegger u should try @princejwesley gist

I was looking for similar solusion as well and I made this after I saw pannous's comment.
Now I'm happy with testing nodegit in REPL.

> syncPromise(require('nodegit')).getRepo('.').o.getCommit(sha).o
Commit { repo: Repository {} }

Removed blocked because unflagged async/await have landed in master.

@joyecheung It would be nice to reference the commit.

@joyeecheung Awesome! Did you have a chance to test it? Does await work in the Repl?

@martinheidegger, in v7.6.0 we have updated V8 to 5.5, which makes it possible to use async functions w/o the --harmony flag, so we can actually get started with implementing. The actual ability of using await in the REPL hasn't been implemented yet.

Apologize for the label shuffling. Didn't realize what it was actually blocking on.

I made a small package https://www.npmjs.com/package/await-outside that you can use as

node --require await-outside/repl

or just


Hope it helps anyone

I just had a quick look at implementing this. Naively wrapping each input line with (async function() { return ${line} })() and changing the callback trigger from cb(err, result) to something like Promise.resolve(result).then(res => cb(null, res), cb) works, but breaks assignments. The await-outside module mentioned above uses a regex hack to redirect assignments to globals, but I worry about how reliable that'd be...

way too hacky if you insert multi line function etc

you might notice that the tests of await-outside do cover multi-line inputs

Hello, I wrote this quick and dirty Babel-based experiment: https://github.com/motet-a/async-repl

It works as described by @Qard, so currently variable declarations are broken. But it鈥檚 not a big deal since we could transform variable declarations into global assigments only in the _global_ scope with Babel, skipping declarations inside inner functions. It鈥檚 not perfect but it could be pretty reliable.

in the mean time you could stub repl with https://github.com/ef4/async-repl

BTW there is an open PR for await support at https://github.com/nodejs/node/pull/15566.

Top-level await is now supported in the REPL. Closing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cong88 picture cong88  路  3Comments

srl295 picture srl295  路  3Comments

willnwhite picture willnwhite  路  3Comments

Icemic picture Icemic  路  3Comments

addaleax picture addaleax  路  3Comments