Как работает promisifyAll, или какие требования к нему работают?

В библиотеке обещаний bluebird есть функция promisifyAll или другие подобные библиотеки, которые утверждают, что преобразуют async-функции с обратными вызовами в обетование, основанное на ie. resolve(), reject() или done().. Так как это работает?

Например:

function myAsync1 (data, url, callBack) {...}

и если я положил его в

Promise.promisify(myAsycn1);

то моя функция будет работать так.

myAsync1('{..}', 'http://..').then(function(){...});

Это беспокоило меня. Есть ли шаблон, в котором должны выполняться обезьяны-обезьяны или функции aync для обезьян Bluebird promisifyAll, чтобы преобразовать их в методы, основанные на обещаниях, или есть какая-то магия, которая их преобразует.

Если нет, то каковы требования и как это работает с существующими библиотеками, такими как mongodb и т.д.

Ответы

Ответ 1

Есть ли шаблон, который должен содержать обезболивающие обезьяны или функции для Bluebird promisifyAll, чтобы преобразовать их в методы, основанные на обещаниях

Да, есть образец. Функции, которые он преобразует, должны ожидать обратного вызова в качестве последнего аргумента. Кроме того, он должен передать ошибку в качестве первого аргумента для обратного вызова (null если нет ошибки) и возвращаемого значения в качестве второго аргумента.

Функция promisify BlueBird очень трудно следовать из-за оптимизации, поэтому я покажу простой способ, которым это могло бы быть написано:

function promisify(fn) {
  return function() {
    var that = this; // save context
    var args = slice.call(arguments); // turn into real array
    return new Promise(function(resolve, reject) {
      var callback = function(err, ret) { // here we assume the arguments to
                                          // the callback follow node.js
                                          // conventions
        if(err != undefined) {
          reject(err);
        } else {
          resolve(ret);
        }
      };
      fn.apply(that, args.concat([callback])); // Now assume that the last argument will
                                              // be used as a callback
    });
  };
}

Теперь мы можем реализовать promisifyAll по функциям целевого объекта и используя promisify для каждого из них.

Ответ 2

Метод promisifyAll() обещает весь модуль или объект, который вызывается как параметр. Это означает, что копия каждого свойства объекта создается с суффиксом Async, который на самом деле является многообещающей версией того же метода, то есть вы можете использовать методы .then() или .done().

Например, если у вас есть метод doSomething() в модуле someModule, после вызова Promise.promisifyAll(someModule) новый метод будет создан в модуле doSomethingAsync(). Вы можете использовать его так:

var someModule = require('some-module');
Promise.promisifyAll(someModule);
someModule.doSomethingAsync().then(function(result) {
    // do whatever you want with result, this function runs after doSomthingAsync() 
    // is finished and the returned value is stored in 'result' variable.
});

Ознакомьтесь с документацией API для bluebird для получения дополнительной информации.