使用带有REPL的应用程序时如何解决承诺

Hed*_*dge 6 javascript node.js promise read-eval-print-loop bookshelf.js

我有一个基本的Node webserver(Koa.js +一个ORM).我喜欢用REPL启动它,这意味着我可以像CLI工具一样使用我的应用程序.

我的所有查询都返回Promises,但我不知道如何在REPL中解决它们.我该如何解决?

例如,以下代码(fetch()查询数据库并返回promise)仅提供此输出 Promise {_bitField: 4325376, _fulfillmentHandler0: undefined, _rejectionHandler0: undefined …}

Transaction.where('reference', '1').fetch().then((res) => return res)
Run Code Online (Sandbox Code Playgroud)

Ben*_*aum 8

更新:Node.js现在默认执行此操作并解析promise


老答案:

您无法正确解决它们 - 但您可以提取它们对全局范围的引用:

> Transaction.where('reference', '1').fetch().then((res) => out = res)
[Object Promise]
> out
  /* your data outputted here since the global was assigned to*/
Run Code Online (Sandbox Code Playgroud)

我们可能会await在未来的Node中允许REPL更干净地解决问题.

  • 使用10.0.0,你需要启动它`node --experimental-repl-await`然后``await Transaction.where(...)` (2认同)

fla*_*usa 5

如果不等待承诺履行,仅设置全局返回值可能(并且经常会)显示错误的结果。

为确保用户履行承诺,您可以向repl服务器提供您自己的评估器:

// sample-repl.js
const repl=require('repl');
function replEvalPromise(cmd,ctx,filename,cb) {
  let result=eval(cmd);
  if (result instanceof Promise) {
    return result
      .then(response=>cb(null,response));
  }
  return cb(null, result);
}
repl.start({ prompt: 'promise-aware> ', eval: replEvalPromise });
Run Code Online (Sandbox Code Playgroud)

这种 REPL 仅在承诺得到解决后才将控制权返回给用户:

$ node sample-repl.js
promise-aware> new Promise(resolve=>setTimeout(()=>resolve('Finished!'),5000));
'Finished!'
promise-aware> out = new Promise(resolve=>setTimeout(()=>resolve('Finished!'),5000));
'Finished!'
promise-aware> out
'Finished!'
promise-aware>
Run Code Online (Sandbox Code Playgroud)

请注意,因为它使用解析值设置了正确的全局返回变量。

标准节点 REPL 的工作方式如下:

> out = new Promise(resolve=>setTimeout(()=>resolve('Finished!'),5000));
Promise { <pending> }
> out
Promise { <pending> }
> out
Promise { <pending> }
> out
Promise { <pending> }
> out
Promise { 'Finished!' }
>
Run Code Online (Sandbox Code Playgroud)