关于解决JS遍历多个异步回调完美引用外部变量的几个办法

2018-08-08  本文已影响228人  turmando

最近项目里用到了多选图片二维码识别上传,由于二维码识别是异步回调,再次列举一下如何在循环回调引用变量

描述

由于JS里for循环是同步任务,而reader.onloadend是异步任务,所以同步的会先执行完循环结束,等到异步回调引用外部变量所以,始终是循环最后一次值,so,归纳了下面三种方式

Promise

Promise.all函数可以并行调用参数中的Promise对象方法,并且将所有Promise对象方法返回值作为数组输入到then回调中

fileReaderPromise = (file) =>{
   let promise = new Promise((resolve, reject) =>{
            let reader = new FileReader()
            reader.readAsDataURL(file)
            reader.onloadend = (e) => {
                let new_result = e.target.result
                resolve(new_result)
            }
   });
   return promise;
}

handle_images = (files) => {
    let filesPromise = files.map(file => this.fileReaderPromise(file))
    Promise.all(filesPromise)
        .then(data => {
            data.map((image,index) => console.log('image',image,'index',index))
        })
}

自执行函数

创建自执行函数局部作用域,保证外部变量不受影响

handle_images = (files) => {
    _.map(files, (file,index) => {
        (function(new_file,new_index){
            let reader = new FileReader()
            reader.readAsDataURL(file)
            reader.onloadend = (e) => {
                let new_result = e.target.result
                //...这里你可以引用new_file,new_index
                console.log('new_file',new_file,'new_index',new_index)
            }
         }.bind(this)(file,index)
    }
}

递归

handle_images = (i) => {
    let new_i = i
    if (new_i<files.length){
        let file = files[i]
        let reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onloadend = (e) => {
            let new_result = e.target.result
            //...
            console.log('file',file,'i',i)
            
            //逻辑处理完后
            new_i++;
            this.handle_images(new_i)
        }
    }
}
//调用
this.handle_images(0)
上一篇下一篇

猜你喜欢

热点阅读