将应用程序与 REPL 一起使用时如何解决承诺

How to resolve promises when using app with REPL

我有一个基本的 Node 网络服务器(Koa.js + 一个 ORM)。我喜欢以 REPL 开头,这意味着我可以像 CLI 工具一样使用我的应用程序。

我所有的查询 return 承诺,但我不知道如何在 REPL 中解决它们。 我该如何解决?

例如下面的代码(fetch() 查询数据库和 returns 一个承诺)只给出这个输出 Promise {_bitField: 4325376, _fulfillmentHandler0: undefined, _rejectionHandler0: undefined …}

Transaction.where('reference', '1').fetch().then((res) => return res)

更新:Node.js 现在默认执行此操作并解决承诺


旧答案:

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

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

我们可能允许await在未来的 Node 中的 REPL 中,这将更干净地解决问题。

有实现此功能的用户空间包,例如 https://github.com/skyrising/await-repl and https://github.com/StreetStrider/repl.js

如果不等待 promise 实现,仅仅设置一个全局 return 值可能(并且经常会)显示错误的结果。

为确保用户履行承诺,您可以向 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 });

这样的 REPL 仅在 promise 得到解决后 return 对用户进行控制:

$ 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>

请注意,它使用已解析的值设置正确的全局 return 变量。

标准节点 REPL 是这样工作的:

> out = new Promise(resolve=>setTimeout(()=>resolve('Finished!'),5000));
Promise { <pending> }
> out
Promise { <pending> }
> out
Promise { <pending> }
> out
Promise { <pending> }
> out
Promise { 'Finished!' }
>