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

时间:2015-04-12 22:36:22

标签: javascript node.js npm bluebird

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

例如:

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

如果我把它放在

Promise.promisify(myAsycn1);

然后我的功能会像这样工作..

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

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

如果没有那么有什么要求以及它如何与mongodb等现有的库一起使用

2 个答案:

答案 0 :(得分:22)

  

是否存在异步非承诺库或函数需要遵循的模式Bluebird promisifyAll将它们转换为基于promises的方法

是的,有一种模式。它转换的函数必须将回调作为最后一个参数。此外,它必须将错误作为回调的第一个参数传递(null,如果没有错误),返回值作为第二个参数。

由于优化,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
    });
  };
}

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

答案 1 :(得分:3)

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

查看bluebird API documentation了解详情。