【问题标题】:How promisifyAll works, or what are the requirements for it work?promisifyAll 是如何工作的,或者它的工作要求是什么?
【发布时间】:2015-06-18 04:19:58
【问题描述】:

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

例如:

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

如果我把它放进去

Promise.promisify(myAsycn1);

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

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

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

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

【问题讨论】:

  • 请注意,您的函数未“转换”,函数是不可变的。相反,Promise.promisify 确实返回了一个 new 函数,该函数将通过回调调用旧函数。
  • @Bergi 它可能是重复的,但它的标题在搜索引擎优化方面措辞如此糟糕,以至于在搜索了四个小时后我没有远程遇到它,事实上它更多的是点击诱饵.
  • 但是,十亿感谢您分享该链接,它确认并澄清了许多事情!!!

标签: javascript node.js npm bluebird


【解决方案1】:

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 了解更多信息。

【讨论】:

  • 我知道最终结果是什么,但我想知道到底是什么?承诺依赖于内部调用并以某种方式传递错误,因此您可以执行 .catch ...所以 doSOthing() 没有显示任何工作。
【解决方案2】:

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

是的,有一个模式。它转换的函数必须期望回调作为它们的最后一个参数。此外,它必须将错误作为第一个参数传递给回调(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
    });
  };
}

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

【讨论】:

  • 所以如果这是约定那么它是否意味着 asyncjs 不遵循约定? gist.github.com/techsin/18a6b6d36ed0205a443a 在这个你可以看到,如果只有回调是第一个参数,函数就可以工作。这种行为是 asyncjs 独有的吗?
  • 对于承诺...规则是函数应该接收回调作为最后一个参数,并且必须以 err 作为第一个参数调用该回调,对吗? ..但是,在他们这边,我看到了Promise.promisify('request'); Promise.promisify('fs'); Promise.promisify('mongoose'); 等示例。巧合的是,所有模块/库都遵循这些要求。
  • @MuhammadUmer 这是使用 async 库的一个非常具有误导性的示例。传递给async.series 的函数预计只接受一个参数,即回调。这些函数永远不会得到err 参数。
  • @MuhammadUmer 这些库都遵循该约定并非巧合。这是所有标准库都使用的强约定,因此不使用它意味着您的代码无法与其他任何人的代码完美兼容。
猜你喜欢
  • 1970-01-01
  • 2011-07-09
  • 2013-02-13
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-06
相关资源
最近更新 更多