项目场景:
该块代码需实现多个文件上传功能,使用for循环input type:file框中的N个上传文件,等所有文件上传成功后调用ajax局部刷新界面,实现实时展示上传文件结果功能问题描述:
原来构想逻辑(接触前端不多 万万没想到代码执行规则不一样):
function uploadStep(file){
// 上传代码 内容就不贴了
}
function refresh_page(){
// 刷新界面代码 内容就不贴了
}
for (let i = 0; i < file.length; i++) {
uploadStep(file[i]) // 上传文件到服务器
})
refresh_page() //调用函数局部刷新界面
问题出在这个for循环是一下子执行完,然后异步执行中间的uploadStep
函数,造成的结果就是我还没上传完呢,refresh_page
函数就执行了,界面在文件上传未完成时就直接刷新了。
解决方案:
使用Deferred
,顾名思义,延迟执行。
不多bb 上代码:
var mdf1 = $.Deferred();
function uploadStep(file, mdf, i, file_length){
// 上传代码 内容就不贴了
// 多加这一行的意思就是当当前文件就是最后一个文件的时候 执行resolve函数
if ((i+1) === file_length){mdf.resolve()}
}
function refresh_page(){
// 刷新界面代码 内容就不贴了
}
function loop(mdf, file_length){
// 将核心代码封装一下,方便调用
for (let i = 0; i < file.length; i++) {
// 相比于原来 多传参数为mdf($.Deferred();) i(当前第几个文件) file_length(总文件数量)
uploadStep(file[i], mdf, i, file_length) // 上传文件到服务器
})
}
// 只有当when里边的函数有resolve操作时(当然还有其他 详细可以自己去了解),done函数才会被执行
// 这里有个坑 .done()里边的函数千万不要带括号 直接写名字就好
$.when(loop(mdf1, file.length)).done(refresh_page)