在nodejs中将异步代码转换为q/promise代码
Converting async code to q/promise code in nodejs
我已经阅读了很多关于 promisejs 的不同文章,但似乎无法让它为我的代码工作。我有异步代码可以工作并且可以满足我的需要,但是它很长而且看起来不像承诺的那样干净。
这是我一直在研究的两个链接: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();
}
}
当前承诺代码(在 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() 但随后不会在承诺代码中打印任何内容。
duplicationUsername
需要 return 一个承诺,否则承诺链接将从调用 callback
中获得值 return(这将是 undefined
).
像这样的东西应该可以工作:
anotherClass.prototype.duplicateUsername = function(usernameFound) {
var deferred = Q.defer();
if (usernameFound) {
deferred.resolve(usernameFound);
} else {
deferred.reject();
}
return deferred.promise;
}
所以我似乎需要 "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)
我已经阅读了很多关于 promisejs 的不同文章,但似乎无法让它为我的代码工作。我有异步代码可以工作并且可以满足我的需要,但是它很长而且看起来不像承诺的那样干净。
这是我一直在研究的两个链接: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();
}
}
当前承诺代码(在 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() 但随后不会在承诺代码中打印任何内容。
duplicationUsername
需要 return 一个承诺,否则承诺链接将从调用 callback
中获得值 return(这将是 undefined
).
像这样的东西应该可以工作:
anotherClass.prototype.duplicateUsername = function(usernameFound) {
var deferred = Q.defer();
if (usernameFound) {
deferred.resolve(usernameFound);
} else {
deferred.reject();
}
return deferred.promise;
}
所以我似乎需要 "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)