Обработчик выполнения обещания не определен

Кажется, что очень простая реализация реализации на основе 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;
});

person jerome    schedule 09.06.2015    source источник
comment
это может быть потому, что handler является анонимной функцией? Вы пытались передать обычную именованную функцию в качестве обработчика?   -  person Avraam Mavridis    schedule 09.06.2015
comment
Вы хотите зарегистрировать value внутри обработчика, а не обещание, возвращенное then   -  person Bergi    schedule 09.06.2015


Ответы (1)


Обработчик then создаст новый объект обещания, который будет возвращен, чтобы можно было связать обещания.

Цитируя документацию bluebird по then,

Возвращает новое обещание, связанное с этим обещанием.


В твоем случае,

sdk.request(options)

возвращает объект обещания, который имеет обработчик выполнения, который является следующим обработчиком then.

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

но обработчик then возвращает новый объект обещания, у которого еще нет обработчика выполнения. Вот почему _fulfillmentHandler0 это undefined.

Вы можете подтвердить это так

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. Один объект обещания может иметь более одного обработчика выполнения. Вот почему вывод выше показывает [Function], что означает массив функций.

Примечание 2. Вам не нужно особо беспокоиться о свойствах объектов Promise. Это детали реализации.


Согласно последнему комментарию,

Я хочу зарегистрировать/проверить данные/значение, возвращаемые sdk.request

Да, вы можете очень хорошо сделать это с Bluebird. Вы можете просто tap обещание, и вы можете распечатать фактическое разрешенное значение, как это

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

напечатает фактическое разрешенное значение, и вы можете прикрепить обработчик then для обработки разрешенного значения.

person thefourtheye    schedule 09.06.2015
comment
Спасибо за разъяснения. Позвольте мне потратить несколько минут, чтобы решить пару вещей, а затем я отмечу этот ответ, если у меня все получится. - person jerome; 09.06.2015
comment
@jerome Если вы хотите зарегистрировать / проверить фактическое разрешенное значение, вы можете использовать функцию tap, как я показал в своем обновленном ответе. - person thefourtheye; 09.06.2015
comment
Все еще работаю над этим. На самом деле у меня есть обещания на пару уровней глубже, но ваш первоначальный ответ привел меня на правильный путь, поэтому отметьте его. - person jerome; 09.06.2015
comment
можно ли манипулировать тапом и попытаться отфильтровать некоторые атрибуты в результирующем объекте. Вместо того, чтобы делать это с функцией .then, потому что у меня есть общий обработчик для функции .then - person Ismail Iqbal; 26.03.2017
comment
@IsmailIqbal Вы можете, но, пожалуйста, не надо. Добавьте еще один обработчик then. - person thefourtheye; 27.03.2017