promisifyAll 是如何工作的,或者它工作的要求是什么?

How promisifyAll works, or what are the requirements for it work?

在 promise 库中,bluebird 具有函数 promisifyAll 或其他类似的库,它们声称可以将具有回调模式的异步函数转换为基于 promise 的 ie。 resolve()reject()done()..那么它是如何工作的?

例如:

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

如果我把它放在

Promise.promisify(myAsycn1);

那我的功能会不会像这样工作..

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

这一直困扰着我。是否存在异步非承诺库或函数需要遵循的模式,以便 Bluebird promisifyAll 将它们转换为基于承诺的方法,或者有一些魔法可以转换它们。

如果没有,那么要求是什么?它如何与 mongodb 等现有库一起使用。

promisifyAll()方法承诺将被调用的整个模块或对象作为参数。这意味着对象的每个 属性 的副本都是用 Async 后缀创建的,这实际上是同一方法的承诺版本,即你可以使用 .then().done()方法就可以了。

例如,如果您在 someModule 模块中有一个 doSomething() 方法,在调用 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.
});

查看 bluebird API documentation 了解更多信息。

Is there a pattern that async non promise libs or function need to follow for Bluebird promisifyAll to convert them to promises based methods

是的,有规律。它转换的函数必须期望回调作为它们的最后一个参数。此外,它必须将错误作为第一个参数传递给回调(null 如果没有错误)并将 return 值作为第二个参数。

BlueBird promisify 函数由于优化而很难遵循,所以我将展示一个简单的编写方法:

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
    });
  };
}

现在我们可以通过循环目标对象中的函数并在每个函数上使用 promisify 来实现 promisifyAll