Promise fulfillment handler undefined

2019-06-19 03:13发布

问题:

Very basic, it seems, implementation of a Promise based implementation is not returning the value/data I expect to see.

This is how I am expecting this interface to work:

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

Here is the code in my model:

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

When I log the return of the model, I see this:

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

When I see _fulfillmentHandler0: undefined that seems to imply that there is no fulfillment handler: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

But the fulfillment handler does seem to be present:

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

回答1:

The then handler will create a new promise object and that will be returned so that the promises can be chained.

Quoting bluebird's documentation on then,

Returns a new promise chained from this promise.


In your case,

sdk.request(options)

returns a promise object and that has a fulfillment handler, which is the following then handler.

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

but the then handler returns a new promise object, which doesn't have a fulfillment handler yet. That is why _fulfillmentHandler0 is undefined.

You can confirm this like this

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

will print

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

since promise has no fulfillment handler yet. But when you attach a handler to it, like this

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

will print

{ _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 }

Note 1: A single promise object can have more than one fulfillment handlers. That is why the output above shows [Function], which means an array of functions.

Note 2: You don't have to worry much about the properties of the Promise objects. These are implementation details.


As per the last comment,

I want to log/verify the data/value returned by the sdk.request

Yes, you can very well do that with bluebird. You can simply tap the promise and you can print the actual resolved value, like this

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

will print the actual resolved value and you can attach a then handler to process the resolved value.