Создание промис-оболочки для старых методов API обратного вызова

Адаптация к стилю асинхронного программирования иногда может быть болезненной. Особенно исходя из опыта программирования, такого как php.

Совсем недавно я вышел из системы.

Я совершил глупейшую ошибку, пытаясь синхронно использовать асинхронный API. На самом деле я возвращал ответ обратного вызова и синхронно присваивал значение переменной.

Вот что я имею в виду.

const apiWrapper = (apiMethodCallArgument) => {
  //apiMethodCall takes time to return a response, 
  //hence it asynchronous
  apiMethodCall(apiMethodCallArgument, (err, responseObject) => {
    if(err) {
      //handle/report error
    }
    return responseObject;
  });
}
//Assigning the response of a function that 
//takes time to respond to a variable.
const apiResponse = apiWrapper(myApiArguments);

Было действительно глупо, если подумать о том, как работает Node.js и цикл событий, думать, что переменная apiResponse будет содержать возвращаемое значение из функции apiWrapper, а скорее будет возвращаться «не определено». Причина этого в том, что в момент вызова функции ответ не готов, поэтому возвращается ответ undefined по умолчанию для вызовов функции, а не фактический объект ответа API.

Простым способом создания собственной оболочки для API было использование промисов. Вот оно. В обратном вызове обещания разрешить я мог бы обрабатывать responseObject чистым способом.

Итак, вот простое решение для создания оболочки Promise для API в стиле обратного вызова.

const promiseApiWrapper = (apiMethodCallArgument) => new Promise ((resolve, reject) => {
  apiMethodCall(apiMethodCallArgument, (err, responseObject) =>
    if(err) {
      //handle/report error
      return reject(err);
    }
    return resolve(responseObject);
  });
});

Итак, давайте поработаем над решением выше.

Функция promiseApiWrapper в основном возвращает обещание. В обратном вызове обещания вызывается основной метод API, который имеет стиль асинхронного обратного вызова; в обратном вызове метод разрешения Promise вызывается с помощью responseObject, если нет ошибки от вызова API, иначе функция отклонения вызывается с объектом ошибки, если это необходимо.

Использование оболочки API упрощается, как и управление объектом ответа. Ниже приведен простой пример того, как я использовал обещанную оболочку API.

promiseApiWrapper(myApiArguments)
  .then(responseObject => {
    //manipulate the responseObject
  })
  .catch(e => {
    //handle the error case
  });

Преимущество создания функции-оболочки Promised API заключается в том, что вы можете аккуратно связать обёртки Promised API и обрабатывать случай ошибки только в одном месте, что делает базу кода более аккуратной и читабельной.

Я надеюсь, что смог поделиться с вами некоторыми полезными сведениями о проблеме преобразования методов API в стиле обратного вызова в обещанные версии API.

Жизнь разработчика — это постоянное обучение.

Недавно я наткнулся на основную функцию Node.js, которая обещает функции обратного вызова из коробки. Вот ссылка на ресурс и по ней легко перейти (Util.promisify). Не стесняйтесь звонить мне, если у вас возникнут проблемы с его использованием 😉.