【问题标题】:Firebase Web 2.4.0 Promises in NodejsNodejs 中的 Firebase Web 2.4.0 承诺
【发布时间】:2016-01-28 02:16:56
【问题描述】:

我在 Node 应用程序中遇到来自 Firebase Web 的错误回调的一些问题。

最初的问题是来自 .set 的错误回调显然没有在我预期的时候被触发。

在调试过程中,我将 Firebase npm 模块升级到最新的 2.4.0(NodeJS 0.10.28),然后注意到异步调用有一个新的 Promise 语法。

我没有找到使用新语法的示例,但做了一个fiddle,它似乎在浏览器中按我预期的方式工作。

var fb = new Firebase("https://katowulf-examples.firebaseio.com/");

// monitors changes and updates UI
try {
  fb.child('sorted_widgets').orderByChild('name').equalTo('one').once('value').then(handleSuccess).catch(handleError)
  fb.child(undefined).once('value').then(handleSuccess).catch(handleError)
  fb.child('sorted_widgets').set(undefined).then(handleSuccess).catch(handleError)

} catch (err) {
  console.error('Caught an error', err)
}

function handleSuccess(snap) {
  console.log('snap: ', snap.val())
}

function handleError(err) {
  console.log('error:', err)
}

我现在尝试在我的 Node 应用程序中使用该语法并收到此错误:

TypeError: Object #<nb> has no method 'catch'
    at myFunction (/node_scripts/my_script.js:514:19)
    at c (/node_modules/firebase/lib/firebase-node.js:238:58)
    at /node_modules/firebase/lib/firebase-node.js:199:710
    at ec (/node_modules/firebase/lib/firebase-node.js:52:165)
    at ac (/node_modules/firebase/lib/firebase-node.js:31:216)
    at bc (/node_modules/firebase/lib/firebase-node.js:30:1259)
    at Ii.h.Ib (/node_modules/firebase/lib/firebase-node.js:218:287)
    at Qh.h.Jd (/node_modules/firebase/lib/firebase-node.js:185:251)
    at Eh.Jd (/node_modules/firebase/lib/firebase-node.js:175:364)

我在摆弄时注意到的一件事是,并非所有错误都被 .catch() 捕获。我将 Javascript Try Catch 放在小提琴中以证明这一点,但这确实是一个单独的问题。

鉴于我在遇到问题的基础上遇到了问题,我想知道我的 Node 安装是否有问题,所以重新安装了 Node 并删除并重新安装了我的 node_modules。我仍然没有任何进展。

有人在 Node 中使用新的 Promise 语法吗?请问有什么建议吗?

【问题讨论】:

  • 也许你的node版本没有实现promise.catch函数,但是浏览器实现了。如果不了解您的节点设置,很难说。要尝试的一件事是引入一个单独的库来处理承诺。蓝鸟是一种流行的。尝试执行npm install bluebird,然后在使用promise 的文件顶部Promise = require("bluebird")
  • 非常可能是对的@AlexKlibisz。你能提供这个答案,以便我投票吗?
  • 我在我的代码中广泛使用了 Promise,并带有“es6-promise”,所以我认为这不是问题。

标签: javascript node.js firebase


【解决方案1】:

我认为发生了 3 件事:

  1. node v0.10.28 没有内置 Promise 实现。
  2. firebase 模块捆绑了一个与 Promise/A+ 兼容的实现,它在尚未定义时使用该实现。
  3. 我们随 firebase 提供的实现是纯 Promise/A+ 实现,不包括 .catch()

不过,.catch() 非常有用,虽然它不是 Promise/A+ 的一部分,但它是半标准的,因此我们计划在即将发布的版本中将其添加到捆绑的 Promise 实现中,这应该可以解决您的问题。

与此同时,您可以执行以下任何操作:

  • 使用.then(null, function(err) { ... }) 而不是.catch(function(err) { ... })
  • 将合适的 Promise 实现导入您的环境。例如。 global.Promise = require('rsvp').Promise;
  • 升级到 node v0.12.x 或更高版本,它带有内置的 Promise 实现(支持.catch())。

【讨论】:

  • 我的脚本有一个依赖关系,它被 NodeJS > 0.10 炸毁,所以我无法升级,但我看到 Firebase Promise 语法在更“现代”版本的 Node.js 上正确工作。谢谢迈克尔!
【解决方案2】:

Firebase 在可用时使用底层 Promise 实现。您的节点环境中的 Promises 实现似乎不支持 catch(),这不是必需的。

从此:

.then(handleSuccess).catch(handleError)

只是一个不同的符号:

.then(handleSuccess, handleError)

你可以选择后者来让它工作。

【讨论】:

  • 请看我上面的评论。我正在广泛使用 es6-promise,这当然支持。赶上
  • Firebase 仅检查与 A+ 规范的兼容性,该规范还没有 catch()。您在 nodejs 上得到的承诺很可能是 goog.Promise
  • 我可以确认您建议的替代符号有效(与上面的蓝鸟答案不同)。但是,我认为期望 Promise 根据 ECMAScript 2015 标准工作是合理的,所以我觉得这是一个错误。
  • firebase.com/blog/2016-01-21-keeping-our-promises.html“我们的承诺是A+兼容”
  • 然后继续说 Firebase 支持“速记捕获”,这是我使用的。 npm 页面还说节点库具有“与 Web 客户端相同的 javascript api”。这似乎是不真实的。
【解决方案3】:

我最初评论的副本:

也许你的 node 版本没有实现 promise .catch 函数,但是浏览器实现了。如果不了解您的节点设置,很难说。

要尝试的一件事是引入一个单独的库来处理 Promise。蓝鸟是一种流行的。尝试执行 npm install bluebird,然后在文件顶部使用 Promise Promise = require("bluebird")。

更多信息:

我现在看到您正在使用 es6-promises polyfill。同样,我对您的节点/转译设置知之甚少,无法确定。一种猜测是,Firebase sdk 源可能需要与 polyfill 一起转译才能对 sdk 生效。因此,暂时使用蓝鸟作为健全性检查可能仍然值得。

【讨论】:

  • @kpg 是的,我可以确认我现在遇到了同样的问题。使用 Babel 6 进行编译,尝试通过 Promise 执行异步/等待时失败。我已经使用防火模块一段时间了,没有任何问题,所以我会坚持一段时间。 github.com/casetext/fireproof
猜你喜欢
  • 2019-03-19
  • 2015-03-30
  • 2018-10-06
  • 2017-04-19
  • 1970-01-01
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多