我有3个函数,我想异步运行,当它们全部完成后运行另一个函数:
app.get('/', function (req, res) {
var homePosts = {
newsest: [],
reviewed: [],
mostPopuler: [],
viewed: []
};
// fetch newest pages and asign the result to 'homePosts.newest '
function fetchNewestPages() {
Post.find({ "type": "public", "featuredImage": { "$exists": true } },"_id title briefDes featuredImage", function (err, posts) {
if (err) {
req.flash('error', 'An unknown error was occured.');
res.redirect('back');
} else {
homePosts.newsest = posts;
}
}).limit(4).sort( { date : -1 } );
}
// fetch most reviewed pages and asign the result to 'homePosts.reviewd '
function fetchMostReviewedPages() {
Post.find({ "type": "public", "featuredImage": { "$exists": true } },"_id title briefDes featuredImage", function (err, posts) {
if (err) {
req.flash('error', 'An unknown error was occured.');
res.redirect('back');
} else {
homePosts.reviewed = posts;
}
}).limit(4).sort( { commentsNumber : -1 } );
}
// fetch most popular pages and asign the result to 'homePosts.mostPopuler '
function fetchMostPopularPages() {
Post.find({ "type": "public", "featuredImage": { "$exists": true } },"_id title briefDes featuredImage", function (err, posts) {
if (err) {
req.flash('error', 'An unknown error was occured.');
res.redirect('back');
} else {
homePosts.mostPopuler = posts;
}
}).limit(4).sort( { likesNumber : -1 } );
}
// now run all 3 functions and when they are done render home page with the homePosts object which contains proper pages
async.parallel([
fetchNewestPages,
fetchMostReviewedPages,
fetchMostPopularPages
], function (err) { // it doesn't run at all
if (err) throw err;
console.log(homePosts);
res.render("home", {homePosts}); // render home page with the proper pages
});
});
希望你得到代码的功能,这里是代码所做的描述:
将呈现主页的最后一个功能根本不会运行。我的问题在哪里?有没有办法同时运行这3个函数然后运行最后一个将呈现页面的函数?
更新:
我已经设法以这种方式做到了,但他们没有同时运行,他们一个接一个地运行。
// fetch newest pages and asign the result to 'homePosts.newest '
function fetchNewestPages(cb) {
Post.find({ "type": "public", "featuredImage": { "$exists": true } },"_id title briefDes featuredImage", function (err, posts) {
if (err) {
req.flash('error', 'An unknown error was occured.');
res.redirect('back');
} else {
homePosts.newsest = posts;
cb();
}
}).limit(4).sort( { date : -1 } );
}
// fetch most reviewed pages and asign the result to 'homePosts.reviewd '
function fetchMostReviewedPages(cb) {
Post.find({ "type": "public", "featuredImage": { "$exists": true } },"_id title briefDes featuredImage", function (err, posts) {
if (err) {
req.flash('error', 'An unknown error was occured.');
res.redirect('back');
} else {
homePosts.reviewed = posts;
cb();
}
}).limit(4).sort( { commentsNumber : -1 } );
}
// fetch most popular pages and asign the result to 'homePosts.mostPopuler '
function fetchMostPopularPages(cb) {
Post.find({ "type": "public", "featuredImage": { "$exists": true } },"_id title briefDes featuredImage", function (err, posts) {
if (err) {
req.flash('error', 'An unknown error was occured.');
res.redirect('back');
} else {
homePosts.mostPopuler = posts;
cb();
}
}).limit(4).sort( { likesNumber : -1 } );
}
fetchNewestPages(function () {
fetchMostReviewedPages(function () {
fetchMostPopularPages(function () {
res.render("home", {homePosts});
});
});
});
答案 0 :(得分:2)
您的问题是您的任何功能都没有回调参数。请记住,当一个函数的处理完成时,您必须调用回调方法。
我在练习中所做的是使用async.constant
作为async.waterfall
或async.parallel
的第一种方法,并传递将在异步方法中使用的数据。在您的情况下,它可以是所有三种方法的搜索条件。
如果在异步方法中没有使用数据,那么我只传递一个空的JS对象。
使用async.constant
可以帮助我做两件事。
在您的情况下,async.constant
方法将包含homePosts
个对象。
app.get('/', function (req, res) {
// fetch newest pages and asign the result to 'homePosts.newest '
function fetchNewestPages(data, callback) {
Post
.find({ "type": "public", "featuredImage": { "$exists": true } },"_id title briefDes featuredImage")
.limit(4)
.sort( { date : -1 } )
.exec(function (err, posts) {
if (err) {
//If we pass first parameter as non-null, the control is passed to the last optional callback skipping all other functions in case of async.waterfall and not waiting for other functions to complete in case of async.parallel
return callback('An unknown error was occured.');
} else {
data['newsest'] = posts; //since homePosts is data object inside this function
If this function is completed successfully then we pass first parameter as null (no error) and second parameter as our object. As the strategy is parallel, all three functions will be editing the same object 'homePosts'
return callback(null, data);
}
});
}
// fetch most reviewed pages and asign the result to 'homePosts.reviewd '
function fetchMostReviewedPages(data, callback) {
Post
.find({ "type": "public", "featuredImage": { "$exists": true } },"_id title briefDes featuredImage")
.limit(4)
.sort( { commentsNumber : -1 } )
.exec(function (err, posts) {
if (err) {
//read comment in first function
return callback('An unknown error was occured.');
} else {
data['reviewed'] = posts; //since homePosts is data object inside this function
//read comment in first function
return callback(null, data);
}
});
}
// fetch most popular pages and asign the result to 'homePosts.mostPopuler '
function fetchMostPopularPages(data, callback) {
Post
.find({ "type": "public", "featuredImage": { "$exists": true } },"_id title briefDes featuredImage")
.limit(4)
.sort( { likesNumber : -1 } )
.exec(function (err, posts) {
if (err) {
//read comment in first function
return callback('An unknown error was occured.');
} else {
data['reviewed'] = posts; //since homePosts is data object inside this function
//read comment in first function
return callback(null, data);
}
});
}
var homePosts = {
newsest: [],
reviewed: [],
mostPopuler: [],
viewed: []
};
// now run all 3 functions and when they are done render home page with the homePosts object which contains proper pages
async.parallel([
async.constant(homePosts),
fetchNewestPages,
fetchMostReviewedPages,
fetchMostPopularPages
], function (err, data) {
//once all functions complete their execution and their callback method is called, with or without error, this method will be called.
if (err) {
req.flash('error', err);
res.redirect('back');
} else {
console.log(data);
res.render("home", {data}); // render home page with the proper pages
}
});
});
希望能够解决您的问题并清除您的概念。
答案 1 :(得分:1)
异步库适用于使用回调的函数。你们没有人这样做。
要么以回调形式重写它们,要么使用像Promise.all这样的东西:
long long t1_rdtsc, t2_rdtsc, ttotal_rdtsc[do_while], ttbest_rdtsc = 99999999999999999, elapsed, elapsed_rdtsc=do_while, overal_time = OVERAL_TIME, ttime=0;
int ii=0;
#define begin_rdtsc\
do{\
asm("#mmmmmmmmmmm");\
t1_rdtsc=_rdtsc();
#define end_rdtsc\
t2_rdtsc=_rdtsc();\
asm("#mmmmmmmmmmm");\
ttotal_rdtsc[ii]=t2_rdtsc-t1_rdtsc;\
}while (ii++<do_while);\
for(ii=0; ii<do_while; ii++){\
if (ttotal_rdtsc[ii]<ttbest_rdtsc){\
ttbest_rdtsc = ttotal_rdtsc[ii];}}\
printf("\nthe best is %lld in %lld iteration\n", ttbest_rdtsc, elapsed_rdtsc);
答案 2 :(得分:0)
希望这有助于你
console.log('start');
// fetch newest pages and asign the result to 'homePosts.newest '
function fetchNewestPages() {
console.log('1')
}
// fetch most reviewed pages and asign the result to 'homePosts.reviewd '
function fetchMostReviewedPages() {
console.log('2')
}
// fetch most popular pages and asign the result to 'homePosts.mostPopuler '
function fetchMostPopularPages() {
console.log('3')
}
fetchNewestPages();
console.log('1 DONE');
fetchMostReviewedPages();
console.log('2 DONE');
fetchMostPopularPages();
console.log('3 DONE');
我的工作也很多。作为示例如果我有很多回调并且某些东西突然不同步那么这个技巧可能很好
var obj = {}
// to somelong stuff here and the result is var result
var result = 'this was generated in the fictive long process above'
objectme.obj = result // those object string can be used anywhere in the script realy nice.
clearInterval(testinterval); // <-- do also here a clearinterval
var testinterval = setInterval(function(){
if (objectme.obj) {
clearInterval(testinterval);
//.. the interval only stop here at the if. you can do anything here. also you can make a timeout. This will force the script to run as you wish it
}
},10000);
非常重要。如果您计划将长代码插入clearinterval区域,则需要增加间隔时间。如果插入的代码花费的时间超过了间隔,那么您的代码将被执行2次。
但是你应该在第一个例子中做。因为使用间隔可能非常棘手。