【问题标题】:Promise fulfillment handler undefined承诺履行处理程序未定义
【发布时间】:2015-08-24 15:53:30
【问题描述】:

看起来非常基本,基于 Promise 的实现没有返回我期望看到的值/数据。

这就是我期望这个界面工作的方式:

sdk.request(options) => Promise~Response → Object (JSON)

这是我模型中的代码:

return sdk.request(options).then(function (value) {
    return value;
});

当我记录模型的返回时,我看到:

{
    _bitField: 0,
    _fulfillmentHandler0: undefined,
    _rejectionHandler0: undefined,
    _progressHandler0: undefined,
    _promise0: undefined,
    _receiver0: undefined,
    _settledValue: undefined
}

当我看到_fulfillmentHandler0: undefined 似乎暗示没有履行处理程序时:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

但履行处理程序似乎确实存在:

return sdk.request(options).then(function (value) {
    // fulfillment handler, right?
    return value;
});

【问题讨论】:

  • 这可能是因为handler 是一个匿名函数吗?您是否尝试将普通命名函数作为处理程序传递?
  • 你想在 handler 中记录value,而不是then返回的承诺

标签: javascript node.js promise bluebird


【解决方案1】:

then 处理程序将创建一个新的 Promise 对象,并将其返回以便可以链接 Promise。

引用bluebird's documentation on then

返回一个新的 Promise,链接自这个 Promise。


在你的情况下,

sdk.request(options)

返回一个 Promise 对象,该对象具有一个实现处理程序,即以下 then 处理程序。

.then(function (value) {
    return value;
});

但是then 处理程序返回一个新的promise 对象,它还没有实现处理程序。这就是为什么_fulfillmentHandler0undefined

你可以这样确认

var promise = require("bluebird").resolve();
console.log(promise);

将打印

{ _bitField: 268435456,
  _fulfillmentHandler0: undefined,
  _rejectionHandler0: undefined,
  _progressHandler0: undefined,
  _promise0: undefined,
  _receiver0: undefined,
  _settledValue: undefined }

因为promise 还没有履行处理程序。但是当你给它附加一个处理程序时,像这样

var promise1 = promise.then(function () {})
console.log(promise);

将打印

{ _bitField: 268435457,
  _fulfillmentHandler0: [Function],
  _rejectionHandler0: undefined,
  _progressHandler0: undefined,
  _promise0: 
   { _bitField: 0,
     _fulfillmentHandler0: undefined,
     _rejectionHandler0: undefined,
     _progressHandler0: undefined,
     _promise0: undefined,
     _receiver0: undefined,
     _settledValue: undefined },
  _receiver0: undefined,
  _settledValue: undefined }

注意 1: 一个 Promise 对象可以有多个履行处理程序。这就是为什么上面的输出显示[Function],这意味着一个函数数组。

注意 2: 您不必太担心 Promise 对象的属性。这些是实现细节。


根据last comment

我想记录/验证sdk.request返回的数据/值

是的,你可以用蓝鸟很好地做到这一点。您可以简单地 tap 承诺,您可以打印实际解析的值,像这样

return sdk.request(options).tap(console.log);

将打印实际解析的值,您可以附加then 处理程序来处理解析的值。

【讨论】:

  • 感谢您的澄清。让我花几分钟时间解决几件事,如果一切正常,我会标记这个答案。
  • @jerome 如果要记录/验证实际解析的值,可以使用tap 函数,就像我在更新的答案中显示的那样。
  • 仍在解决这个问题。我实际上有几个层次的承诺,但你最初的回答让我走上了正确的轨道,所以标记它。
  • 是否可以通过点击进行操作并尝试过滤结果对象中的某些属性。而不是在 .then 函数上执行此操作,因为我有 .then 函数的通用处理程序
  • @IsmailIqbal 你可以,但请不要。添加另一个 then 处理程序。
猜你喜欢
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
  • 2015-11-17
相关资源
最近更新 更多