最近項目里用到了多選圖片二維碼識別上傳,由于二維碼識別是異步回調(diào),再次列舉一下如何在循環(huán)回調(diào)引用變量
描述
由于JS里for循環(huán)是同步任務,而reader.onloadend是異步任務,所以同步的會先執(zhí)行完循環(huán)結(jié)束,等到異步回調(diào)引用外部變量所以,始終是循環(huán)最后一次值,so,歸納了下面三種方式
Promise
Promise.all函數(shù)可以并行調(diào)用參數(shù)中的Promise對象方法历等,并且將所有Promise對象方法返回值作為數(shù)組輸入到then回調(diào)中
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))
})
}
自執(zhí)行函數(shù)
創(chuàng)建自執(zhí)行函數(shù)局部作用域,保證外部變量不受影響
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)
}
}
}
//調(diào)用
this.handle_images(0)