问题
I've read through a lot of different articles on promisejs but can't seem to get it to work for my code. I have async code that works and does what I need but it's very long and doesn't look as clean as it could with promise.
Here's the two links I've been really looking into: http://jabberwocky.eu/2013/02/15/promises-in-javascript-with-q/ and 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();
}
}
current promise code (in 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;
});
When I run my promise code, it goes to duplicateUsername, does callback() but then doesn't print anything in the promise code.
回答1:
duplicationUsername
needs to return a promise, otherwise the promise chaining will get the value returned from calling callback
(which would be undefined
).
Something like this should work:
anotherClass.prototype.duplicateUsername = function(usernameFound) {
var deferred = Q.defer();
if (usernameFound) {
deferred.resolve(usernameFound);
} else {
deferred.reject();
}
return deferred.promise;
}
回答2:
So it seems like I needed to "promisify" my own functions before I could use them.
Here's how I did it with 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;
});
}
Here's how to do it with Bluebird:
userCheck.prototype.duplicateUsername = function(usernameFound) {
return new Promise(function(resolve, reject) {
if (usernameFound) {
reject("error");
} else {
resolve();
}
});
}
Then in my mainClass, I just used them by calling the methods and then .then(//blah)
来源:https://stackoverflow.com/questions/28521117/converting-async-code-to-q-promise-code-in-nodejs