Node.js - 函数调用返回未定义并稍后求值
Node.js - Function call returning undefined and evaluated later
我正在使用异步模块并行执行一组函数。但是我在这些函数的回调中使用了另一个函数的 return 值。但问题是,函数 returns as undefined as callback 不会等待它被评估。
function getGenresId(genres){
var genresArr = parseCSV(genres);
Genre.find({name: {$in: genresArr } }, function (err, genres) {
var genresId = genres.map(function (genre) {
return genre.id;
});
return genresId.toString();
});
}
async.parallel({
getGenres: function (callback) {
if(checkempty(req.query.genres) === true){
callback(null, getGenresId(req.query.genres)});
}
else{
callback(null, '');
}
},
getActor: function (outercallback) {
if(checkempty(req.query.actors) === true) {
//other code here
}
else{
outercallback(null, '');
}
}
);
我知道函数 getGenresId() 包含对数据库的阻塞调用,Node.js 将异步处理它。但是有什么办法可以强制
callback(null, getGenresId(req.query.genres)});
评估 getGenresId 函数并等待它 return 一个值,然后再继续。我可以在这里使用 async 的系列函数,但是有 native/better 方法来做到这一点吗?
对 node.js 使用 Q,您可以 return 来自 getGenresId
函数的承诺,等待它被解决,然后调用 callback
解决后:
var Q = require('q');
function getGenresId(genres){
var deferred = Q.defer(); // creating the promise
var genresArr = parseCSV(genres);
Genre.find({name: {$in: genresArr } }, function (err, genres) {
var genresId = genres.map(function (genre) {
return genre.id;
});
deferred.resolve(genresId.toString()); // resolving the prmoise
});
return deferred.promise; // returning the promise
}
async.parallel({
getGenres: function (callback) {
if(checkempty(req.query.genres) === true){
//waiting for the promise
getGenresId(req.query.genres).then(function(data) {
callback(null, data);
});
}
else{
callback(null, '');
}
....
问题是以下假设:
I do understand that the function getGenresId() contains a blocking call to the database
...因为 getGenresId
根本没有阻塞。它 returns undefined
立即(第 9 行),然后最终在您的数据库上运行查询。它不会阻止来自 运行 的任何其他内容,因此它是 非阻塞。
你能把数据库调用改为阻塞吗?有点(async-await
、generators
),但不要打扰,因为您已经接近现有代码了。它只需要一个小的改变就可以工作:
// This function has a new argument, one named 'callback'.
function getGenresId(genres, callback){
var genresArr = parseCSV(genres);
Genre.find({name: {$in: genresArr } }, function (err, genres) {
if(err) {
callback(err);
return; // Stop processing the rest of the function.
}
var genresId = genres.map(function (genre) {
return genre.id;
});
// Instead of the `return` statement, we call the callback.
callback(null, genresId.toString());
});
}
async.parallel({
getGenres: function (callback) {
if(checkempty(req.query.genres) === true){
// Call the function by passing the list of
// genres & this function's callback.
// Functions are ordinary values.
getGenresId(req.query.genres, callback);
}
else{
callback(null, '');
}
},
...
看看 callback
(传递给 getGenresId
函数)是如何仅在您的数据库结果输入后才被调用的?这就是这样做的方法。您拥有的 return 语句的值 (return genresId.toString();
),因为它在非阻塞和异步函数(数据库调用)中,被丢弃了。
其他选项(承诺、生成器等)也是有效的方法,但您已经使用的 async
模块没有任何问题。
我正在使用异步模块并行执行一组函数。但是我在这些函数的回调中使用了另一个函数的 return 值。但问题是,函数 returns as undefined as callback 不会等待它被评估。
function getGenresId(genres){
var genresArr = parseCSV(genres);
Genre.find({name: {$in: genresArr } }, function (err, genres) {
var genresId = genres.map(function (genre) {
return genre.id;
});
return genresId.toString();
});
}
async.parallel({
getGenres: function (callback) {
if(checkempty(req.query.genres) === true){
callback(null, getGenresId(req.query.genres)});
}
else{
callback(null, '');
}
},
getActor: function (outercallback) {
if(checkempty(req.query.actors) === true) {
//other code here
}
else{
outercallback(null, '');
}
}
);
我知道函数 getGenresId() 包含对数据库的阻塞调用,Node.js 将异步处理它。但是有什么办法可以强制
callback(null, getGenresId(req.query.genres)});
评估 getGenresId 函数并等待它 return 一个值,然后再继续。我可以在这里使用 async 的系列函数,但是有 native/better 方法来做到这一点吗?
对 node.js 使用 Q,您可以 return 来自 getGenresId
函数的承诺,等待它被解决,然后调用 callback
解决后:
var Q = require('q');
function getGenresId(genres){
var deferred = Q.defer(); // creating the promise
var genresArr = parseCSV(genres);
Genre.find({name: {$in: genresArr } }, function (err, genres) {
var genresId = genres.map(function (genre) {
return genre.id;
});
deferred.resolve(genresId.toString()); // resolving the prmoise
});
return deferred.promise; // returning the promise
}
async.parallel({
getGenres: function (callback) {
if(checkempty(req.query.genres) === true){
//waiting for the promise
getGenresId(req.query.genres).then(function(data) {
callback(null, data);
});
}
else{
callback(null, '');
}
....
问题是以下假设:
I do understand that the function getGenresId() contains a blocking call to the database
...因为 getGenresId
根本没有阻塞。它 returns undefined
立即(第 9 行),然后最终在您的数据库上运行查询。它不会阻止来自 运行 的任何其他内容,因此它是 非阻塞。
你能把数据库调用改为阻塞吗?有点(async-await
、generators
),但不要打扰,因为您已经接近现有代码了。它只需要一个小的改变就可以工作:
// This function has a new argument, one named 'callback'.
function getGenresId(genres, callback){
var genresArr = parseCSV(genres);
Genre.find({name: {$in: genresArr } }, function (err, genres) {
if(err) {
callback(err);
return; // Stop processing the rest of the function.
}
var genresId = genres.map(function (genre) {
return genre.id;
});
// Instead of the `return` statement, we call the callback.
callback(null, genresId.toString());
});
}
async.parallel({
getGenres: function (callback) {
if(checkempty(req.query.genres) === true){
// Call the function by passing the list of
// genres & this function's callback.
// Functions are ordinary values.
getGenresId(req.query.genres, callback);
}
else{
callback(null, '');
}
},
...
看看 callback
(传递给 getGenresId
函数)是如何仅在您的数据库结果输入后才被调用的?这就是这样做的方法。您拥有的 return 语句的值 (return genresId.toString();
),因为它在非阻塞和异步函数(数据库调用)中,被丢弃了。
其他选项(承诺、生成器等)也是有效的方法,但您已经使用的 async
模块没有任何问题。