Почему Promisification терпит неудачу для некоторых методов, но не для всех?

jsonix библиотека не следует first argument must be an error Соглашение, поэтому я решил использовать Bluebird и обещать это так:

    return new Promise(function(resolve, reject) {
      try {
        unmarshaller.unmarshalString(xmlResponse,
          function (unmarshalled) {
            ...
            resolve(unmarshalled);
          });
      }
      catch (error) {
        reject(error);
      }
    });

Но это висит бесконечно! Тогда как, если я просто сохраню xmlResponse в файл, а затем обработать его другим методом: unmarshalFile... обещание, кажется, работает просто отлично!

    return new Promise(function(resolve, reject) {
      try {
        unmarshaller.unmarshalFile('test1.xml',
          function (unmarshalled) {
            ...
            resolve(unmarshalled);
          });
      }
      catch (error) {
        reject(error);
      }
    });

Итак, мой вопрос: почему обещание провалилось для одного метода, а не для другого?

2 ответа

Решение

Когда я смотрю на код для jsonix, я не вижу никакой функции обратного вызова для .unmarshalString() и, глядя на реализацию, нет ничего асинхронного в реализации и ничего, что вызывает обратный вызов. Он просто возвращает ответ напрямую. Таким образом, функция является синхронной, а не асинхронной и возвращает свое значение непосредственно в качестве возвращаемого значения.

Для справки, .unmarshalURL() а также .unmarshalFile() принять обратный вызов и иметь асинхронную реализацию - .unmarshalString() это просто другое.

Таким образом, вам не нужно использовать обещания с unmarshaller.unmarshalString(xmlResponse) совсем. Вы можете просто вернуть прямое значение:

return unmarshaller.unmarshalString(xmlResponse);

Если вы хотите обернуть его в обещание согласованности интерфейса между всеми тремя методами, вы можете сделать это:

try {
    return Promise.resolve(unmarshaller.unmarshalString(xmlResponse));
} catch(err) {
    return Promise.reject(err);
}

Или вы можете использовать Bluebird's Promise.method() обернуть это для вас:

return Promise.method(unmarshaller.unmarshalString.bind(unmarshaller, xmlResponse));

Отказ от ответственности: я автор Jsonix.

unmarshalURL а также unmarshalFile являются асинхронными (и должны быть), но unmarshalString или же unmarshalDocument не асинхронны (и не должны быть).

Другие вопросы по тегам