在nodejs中将异步代码转换为q / promise代码

时间:2015-02-14 22:42:07

标签: node.js asynchronous promise q

我已经阅读了很多关于promisejs的不同文章,但似乎无法让它为我的代码工作。我有异步代码可以工作并且做我需要的但是它很长并且看起来不那么干净。

以下是我真正关注过的两个链接:http://jabberwocky.eu/2013/02/15/promises-in-javascript-with-q/https://spring.io/understanding/javascript-promises

mainCode.js

accountModel.findOne({username: body.username}, function(err, usernameFound) {
    console.log("here");
    if (err) {
        console.log(err);
    } else {
        console.log("here1");
        anotherClass.duplicateUsername(usernameFound, function(err, noerr) {
            if (err) {
                console.log("error");
                res.status(409).send("username");
            } else {
                console.log("here2");
                accountModel.findOne({email: body.email}, function(err, emailFound) {
                    if (err) {
                        console.log("error2");
                    } else {
                        console.log("here3");
                        console.log(emailFound);    
                    }
                });
            }
        });
    }
});

// anotherclass.duplicateUsername

anotherClass.prototype.duplicateUsername = function(usernameFound, callback) {
    if (usernameFound) {
        callback(usernameFound);
    } else {
        callback();
    }
}

当前的承诺代码(在mainCode.js中):

var promise = userModel.findOne({
    username: body.username
}).exec();

promise.then(function(usernameFound) {
    console.log("usernameFound")
    return userCheck.duplicateUsername(usernameFound);
}).then(function(usernameFound) {
        console.log("NOERR:" + usernameFound + ":NOERR");
        console.log("noerror");
        return;
    }, function(error) {
        console.log(err);
        console.log("error");
        res.sendStatus(409);
        return;
    });

当我运行我的承诺代码时,它会转到duplicateUsername,执行callback()但不会在promise代码中打印任何内容。

2 个答案:

答案 0 :(得分:0)

duplicationUsername需要返回一个promise,否则promise链接将获得从调用callback返回的值(undefined)。

这样的事情应该有效:

anotherClass.prototype.duplicateUsername = function(usernameFound) {
    var deferred = Q.defer();
    if (usernameFound) {
        deferred.resolve(usernameFound);
    } else {
        deferred.reject();
    }
    return deferred.promise;
}

答案 1 :(得分:0)

所以我似乎需要" promisify"在我使用它们之前我自己的功能。

这是我用Q做的:

var Q = require('q');
anotherClass.prototype.duplicateUsername = function(username, callback) {
    return new Promise(function(resolve, reject) {
        var deferred = Q.defer();

        if (usernameFound) {
            deferred.reject("error);
        } else {
            deferred.resolve("no err: duplicate username");
        }

        deferred.promise.nodeify(callback);
        return deferred.promise;
    });
}

以下是如何使用Bluebird:

userCheck.prototype.duplicateUsername = function(usernameFound) {
    return new Promise(function(resolve, reject) {
        if (usernameFound) {
            reject("error");
        } else {
            resolve();
        }
   });
}

然后在我的mainClass中,我通过调用方法然后使用它们然后.then(// blah)