在使用promise处理异步问题时,遇到坑
前端有些异步效果可以使用promise解决
<script>
// 1. jquery实现
// let data = ["./img/back.jpg","./img/back.jpg","./img/back.jpg","./img/back.jpg","./img/back.jpg","./img/back.jpg" ];
//不考虑先后顺序 不需要使用promise
// for(let i = 0; i< $("li").length; i ++) {
// $("li").eq(i).css({"animation": "img-show .5s "+ i * 0.3 +"s linear forwards"})
// }
// 2. 递归函数 原生js写 ---- 时间是根据当前索引确定的
// let lis = document.getElementsByTagName("li");
// function exector(el,index) {
// el.style.animation = "img-show .5s "+ index * 0.3 +"s linear forwards";
// }
// Array.prototype.forEach.call(lis, (item,index) => {
// exector(item,index)
// })
//3. 使用promise ---- 时间是根据上一个执行完后执行下一个
//定义一个固定时间回调函数
let lis = document.getElementsByTagName("li");
function setAnimation(el,delay) {
return new Promise((resolve, reject) => {
setTimeout(() => {
el.style.animation = "img-show .5s "+ 0.3 +"s linear forwards";
resolve(123)
}, delay)
})
}
async function main() {
//必须使用传统变量方式 for for..in
for(let i = 0; i < lis.length; i ++) {
await setAnimation(lis[i], 300)
}
//失败
//因为 forEach 没有返回值, 如果使用 map 返回的是 promise对象数组 ,await处理不了
// Array.prototype.forEach.call(lis, async function(el,index){
// await setAnimation(el, 300)
// })
//失败
// let arr = Array.from(lis);
// await Promise.all(arr.map(async item => {
// const res = await setAnimation(item)
// console.log(res)
// }))
// console.log('end')
}
main();
</script>
forEach/map与async/await使用踩坑
-
foreach
1、首先这是因为foreach是没有return返回值的(可以自己去跟下源码,foreach内 部实现只是简单的回调)2、而foreach里面的回调函数因为加了async的原因,所以默认会返回一个promise,但是因为foreach的实现并没有返回值,所以导致返回的这个promise对象没人去管了
-
map
- 我们会发现其实map返回的并不是一个promise对象,而是一个包含promise对象的数组[promise, promise, promise],其中每个promise对象都是循环迭代产生的结果。而await是处理不了数组的,它只能处理promise对象。
注意
我们在使用promise解决异步逻辑问题时,还是异步效果问题时,尽量使用传统的遍历方法,在开发中,我们解决复杂异步js逻辑问题时,结合promise对象,发布订阅模式去解决这类问题
网友评论