Node.js 试图了解Promission如何与BlueBird合作

Node.js 试图了解Promission如何与BlueBird合作,node.js,bluebird,Node.js,Bluebird,我正试图用这个词来表达我的承诺 下面是一个简单的例子,它并不像我预期的那样有效 var Promise = require("bluebird"); var myObj = { add: function(op1, op2) { return op1 + op2; } }; // Sync call to add method -> 7 console.log(myObj.add(3,4)); var myObjAsync = Promise.promisifyAll

我正试图用这个词来表达我的承诺

下面是一个简单的例子,它并不像我预期的那样有效

var Promise = require("bluebird");

var myObj = {
  add: function(op1, op2) {
    return op1 + op2;
  }
};

// Sync call to add method -> 7
console.log(myObj.add(3,4));

var myObjAsync = Promise.promisifyAll(myObj);

// Async call to promisified add method -> nothing written to console
myObjAsync.addAsync(2,3).then(function(data) {
  console.log(data);
  return data;
})
我要么错过了一些(主要的)承诺概念,要么错过了蓝鸟

提前感谢你的帮助

编辑:根据jfriend00的反馈进行修订(目前正在使用的版本)

var Promise = require("bluebird");

var myObj = {
  add: function(op1, op2) {
    return op1 + op2;
  }
  , add2: function(op1, op2, callback) {
    callback(null, op1 + op2);
  }

};

// Sync call to add method -> 7
console.log(myObj.add(3,4));

var myObjAsync = Promise.promisifyAll(myObj);

// Async call to promisified add method -> nothing written to console
myObjAsync.addAsync(2,3).then(function(data) {
  console.log("%j", data);
  return data;
})

// Async call to promisified add2 method -> 5
myObjAsync.add2Async(2,3).then(function(data) {
  console.log("%j", data);
  return data;
})
要使
promisifyAll()
正常工作,函数必须是异步的,传递给函数的最后一个参数必须是完成回调,完成回调必须有一个错误参数作为其第一个参数,当没有错误时该参数为false,返回值作为第二个参数(如果有值)

您的函数不符合这些条件中的任何一个


以下是一段摘录自:

假设目标方法符合node.js回调 接受回调作为最后一个参数并调用该参数的约定 回调,错误为第一个参数,成功值为 第二个论点。如果节点方法使用多个 成功值,则实现值将是它们的数组

请记住,
.promisifyAll()
不能将同步操作转换为异步操作。is所做的是采用符合特定调用约定的异步操作,并通过挂接回调并测试回调的参数来检测成功或失败并传播返回值,从而将其封装到承诺中


如果你对Bluebird是如何做到这一点感到好奇,你可以检查他们的实际代码,尽管如果没有一些重要的研究,要准确地理解它是如何做到的并不容易

这里是promisify函数的一个更简单的版本,看看它能做些什么(我建议对它的所有其他功能使用Bluebird,而不是这个)

//--------------------------------------------------------------
//承诺(fn,obj)
//
//传递一个异步函数,该函数将回调作为其最后一个参数
//符合node.js回调调用约定函数(err,result)
//通过obj是可选的。如果存在,将调用传入的函数
//as obj.method()
//
//Returns:调用时将返回承诺的新函数。
// --------------------------------------------------------------
功能承诺(fn、obj){
if(fn类型!=“功能”){
抛出新错误(“promisify()的fn参数必须是函数”);
}
//obj是可选的,可能未定义
//如果存在,它将被用作在obj.fn()中调用fn的上下文
返回函数(/*args*/){
//将arguments对象的副本复制到实际数组中
//不会阻止解释器优化
var args=新数组(arguments.length);
对于(变量i=0;i如果(arguments.length谢谢你,这帮我找到了这个奇怪的问题,直到你的评论我才意识到使用
mongoskin
MongoClient.connect是行不通的,因为它没有回调!我把它换回了
mongodb
MongoClient.connect,在lib上运行
promisifyAll
,然后解决了它。S我很抱歉。在你编辑它的时候,不知怎的偶然发现了这个权利,而这个编辑正是我想要的:哦,谢谢。
// --------------------------------------------------------------
// promisify(fn, obj)
//
// Pass an async function that takes as its last argument a callback
// that conforms to the node.js callback calling convention function(err, result)
// passing obj is optional.  If present the function passed in will be called
// as obj.method()
//
// Returns: New function that when called will return a promise.
// --------------------------------------------------------------

function promisify(fn, obj) {
    if (typeof fn !== "function") {
        throw new Error("fn argument to promisify() must be function");
    }
    // obj is optional and may be undefined
    // if present, it will be used as context to call fn as in obj.fn()
    return function(/* args */) {
        // make copy of arguments object into a real array in a way that
        // does not prevent interpreter optimizations
        var args = new Array(arguments.length);
        for (var i = 0; i < args.length; i++) {
            args[i] = arguments[i];
        }
        return new Promise(function(resolve, reject) {
            // add our callback function at the end of the args list
            var resultMany;
            args.push(function(err, result) {
                if (err) {
                    reject(err);
                } else {
                    // if 0 or 1 result, then just return it as a simple value
                    if (arguments.length <= 2) {
                        resolve(result);
                    } else {
                        // if more than one result came with the callback function, 
                        // then put it into an array so we can resolve with a single value (the array of results)
                        // skip the first argument which is the err value
                        resultMany = new Array(arguments.length - 1);
                        for (var i = 0; i < arguments.length - 1; i++) {
                            resultMany[i] = arguments[i + 1];
                        }
                        resolve(resultMany);
                    }
                }
            });
            // call original function with our callback as last argument
            fn.apply(obj, args);
        });
    }
}