【问题标题】:How to resolve promises when using app with REPL使用带有 REPL 的应用程序时如何解决 Promise
【发布时间】:2017-10-25 10:57:52
【问题描述】:

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

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

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

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

【问题讨论】:

  • 这看起来很像 Bluebird 的承诺。在这种情况下,您可以在以下行中执行_.value()

标签: javascript node.js promise read-eval-print-loop bookshelf.js


【解决方案1】:

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


旧答案:

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

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

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

【讨论】:

  • 哇,这太棒了,可以为我节省大量时间。是否有关于在 REPL 中包含 await 的持续讨论?让它登陆 8.0 将是炸弹:)
  • 打开了一个问题来跟踪github.com/nodejs/node/issues/13209
  • 这适用于哪个版本的 Node.js?我似乎无法让它工作。谢谢。
  • @mfulton26 9.x 最新版本和 10.x 每晚版本
  • 使用 10.0.0,需要先启动node --experimental-repl-await,然后再启动await Transaction.where(...)
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    为确保用户履行承诺,您可以向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 得到解决后将控制权返回给用户:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 2020-08-02
      • 2016-06-01
      • 1970-01-01
      相关资源
      最近更新 更多