async的concatSeries循环里面,嵌套回调函数同步问题【已解决,感谢jiangmiao同学】
发布于 12 年前 作者 yandaoyong 7832 次预览 最后一次回复是 12 年前 来自
handler.myTasklist = function(msg,session,next){
var uid = session.uid;
taskDao.myTasklist(uid,function(err,res){
//res为一个数组,这里使用async的concatSeries方法,同步依次执行
async.concatSeries(res,function(task,callback){
var taskinfo;
//这里出现问题,直接跳过了taskDao,直接进入callback(null,data[taskinfo])了,正确的方法该怎样写呢?
taskDao.taskAttribute(task.id,function(err,res){
var attributes = []
for(var j=0;j<res.length;j++){
var attribute = {
title:res[j].title,
attributevalue:res[j].attributevalue
};
attributes.push(attribute);
}
taskinfo = {
title:task.title,
type:task.type,
status:task.status,
attributes:attributes
};
});
//将得到的taskinfo传入回调函数,由于没有同步taskDao.taskAttribute,直接导致这里到taskinfo为空
callback(null,data[taskinfo]);
},function(err,values){
console.log("tasks:"+values);
next(null,{
route: 'onMytasklist',
tasks:values
});
});
});
};
要求就是:for循环里面 先执行taskDao.taskAttribute,取得taskinfo后 再执行下面的callback(null,data[taskinfo]);这个回调
希望不要嫌弃新人技术哈
【已解决,改变一下callback位置即可】
17 回复
所有的循环都可以改写其异步形式,如for循环
的异步版本则是
如果条件简单,也可合并写成
不好意思,我是需要同步
就是for循环里面,先执行嵌套的taskDao.taskAttribute这个回调函数,然后再执行callback
现在的问题是,直接跳过了嵌套的taskDao.taskAttribute这个回调函数
要求就是:for循环里面 先执行taskDao.taskAttribute,取得taskinfo后 再执行callback这个回调
@yandaoyong 如果你执行的taskAttribute是异步,那么整个循环就是异步。
@yandaoyong 如果要让callback在异步taskAttribute后执行,callback肯定要存在于taskAttribute的回调函数中。解决方法参见我的回答。要让包含异步循环顺序执行必须用异步的方式写循环。
@jiangmiao
我循环用的是concatSeries,这个方法是同步挨个执行的
@jiangmiao 怎么改一下taskAttribute,让它和callback同步?
@yandaoyong 同步的话callback就不会执行在taskAttribute之前。
@yandaoyong 如果要让callback在异步taskAttribute后执行,callback肯定要存在于taskAttribute的回调函数中。
@jiangmiao
@yandaoyong
@yandaoyong 哪里是异步的终点写哪里,如果终点被隐藏,重写代码。
@jiangmiao
感谢,搞定
那么简答,真为自己惭愧啊
@yandaoyong 客气,我也没看仔细看问题,看到你另一个循环的贴子就回了个循环异步的变换,异步流程上的所有问题都可以用类似的方法拆解改写。
@jiangmiao 上次你说到循环改写异步的问题, 我来自卖自夸了. 楼主另一个帖子里 (话说那个帖子删了? 我只好贴这里来了见谅) 那段代码改写成 Stekinscript 异步管道形式如下 (# 号之后是注释, 对比原有的 js 代码)
用 Stekinscript 最新分支编译, 产生等价于 (之所以说等价于, 是删去一些无用语句并且进行代码格式化之后的结果) 下面的 js 代码, 将管道也就是循环中的异步改写成递归, 并且将之后的语句 (
next调用, 因为 stekinscript 会作一些 name mangle 因此生成的代码中叫做$c_next) 放在递归的末尾执行请多指教.
很好很强大,如果循环中要并发而不是顺序执行不知是否支持。
可以参考 IcedCoffeeScript的话await for为并发,for … await 则为顺序。
比如
输出为
@jiangmiao 惭愧, 还没这种支持. 很有意思的样子, 得看看生成的 js 代码是怎么布置的.