async/await与for循环遍历
发布于 7 年前 作者 ZCZ12138 11214 次预览 最后一次回复是 7 年前 来自 问答
遇到了在for循环中,使用await函数的情况,但是打断点调试后发现得到的还是Promise{pending},有考虑闭包的问题,使用了匿名函数带参数的写法,还是不能解决,每次单步调试的时候await函数那里会自动跳过,代码如下,请熟悉这方面的朋友给点意见,指明一个研究方向,谢谢。
var query = models.DuoBaoPlayer.find(q, '').sort('-_id').skip(skipFrom).limit(limit);
query.exec(function(err, doc) {
var dataList = [];
async function findOneDuobao(item) {
let doc = await models.DuoBao.findOne({id:item.sid}, 'title startTime endTime luckys totalTime haveTime winner'); //mongoose
return doc;
}
for (let i = 0; i < doc.length; i++) {
dataList.push((async function (num) {
let data1 = doc[num].toObject();
let data2 = await findOneDuobao(doc[num]); //每次单步调试的时候都会自动跳过
let data = Object.assign(data1, data2);
return data;
})(i));
}
let testDataList = dataList; //return 两个 Promise { pending }
}20 回复
打开下面的网页自己试一下。
http://www.typescriptlang.org/play/index.html#src= let arr %3D [] for (let i %3D 0%3B i < 2%3B i%2B%2B){ const ret %3D ((async (i) %3D> { return Promise.resolve(i) })(i))%3B%0D%0A%20%20%20%20arr.push(ret)%0D%0A%7D%0D%0A%0D%0Aconsole.log(arr)%0D%0A%0D%0A
没问题的,自己 catch 一下。
async 函数返回的就是一个 Promise,你的 datalist push 进去的当然也是个 pending 状态的 Promise,所以里面的 await 调试取值的时候也是一个 pending 状态的 Promise,当然也就看起来跳过了
先不说别的,你上面代码中是不是漏了什么,doc 没有声明啊,或者忘执行函数了
@rrbe 我想得到的是resolve之后的值,有什么办法能够让它完成后再执行呢
@ZCZ12138 当然参考是 2 楼朴灵大大的回复~ 哈哈 当然你要把外层也用 async 函数包起来
@Michaelooo function(err, doc) { }
@ZCZ12138 眼瞎没看到……其他的感觉没毛病啊,我测的OK啊
@JacksonTian 您的建议确实让人耳目一新,但我测试后发现all之后的值少了一个字段,不太确定是不是这样写的原因,我改用async.eachSeries是可以获取到完整的数据的,而且请求在Chrome里面没有response data,这是为什么?
async (xxx) => { const query = await model.xx.find(); if(query && query.length) { for(let i in query){ let data = await model.xxx.find(i) } } }
我平时就是这样用的,不知道是否符合你的要求
ref https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
有始有终一下,Promise.all确实有效,少字段是因为assign函数的问题,没有response data是因为浏览器,感谢大家的建议。另外有关于遍历中的异步操作,大家有什么更好的建议请不要吝啬,随意砸到我脸上 》_《
我觉得大家没有引导楼主到正确的姿势上额,楼主对async 和 await 还缺一点点更深刻的理解,这里给你个引导吧:
@fantasticsoul await就是在async函数的promise变为resolved后,相当于.then((value) => {}),而不加await关键字只是个待完成的promise而已,而我题目中明明已经await了,但还是不能等到了resolved后才执行下文,这让我很困惑,或许还是陷入怪圈出不来了 (ノへ ̄、)
@ZCZ12138
@qiu363 因为 async 返回的是一个 promise
@ZCZ12138 谷歌浏览器console里执行如下代码,没问题啊
你试一下push()里面的匿名函数执行完后给个.then(result => result) ,这样push((async fun)(i).then(result => result)), 不知道行不行,如果可以 那么 在前面 加个push( await (async funtion(){})(i)) 应该也可以
试了一下 发现 加.then()那个不可以的,await匿名函数前面加个 await是可以的,第一个不行的原因不太清楚,报的错是[ Promise { [Circular] }, Promise { [Circular] } ],