Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS基础测试36期 #38

Open
zhangxinxu opened this issue Aug 14, 2019 · 31 comments
Open

JS基础测试36期 #38

zhangxinxu opened this issue Aug 14, 2019 · 31 comments

Comments

@zhangxinxu
Copy link
Owner

本期小测源自Ajax多文件上传这个实际需求,内容如下:

答题前不要看别人回答,答题后可以,但不能修改自己回答

大家提交回答的时候,注意缩进距离,起始位置从左边缘开始;另外,github自带代码高亮,所以请使用下面示意的格式。

```js
// 你的JS代码写在这里
 ```

其它:

  1. 首位答题者可获得直播翻牌机会;
  2. 本次答疑直播为8月17日上午10:00,大约30分钟;
@XboxYan
Copy link

XboxYan commented Aug 14, 2019

1.

var xhr = new XMLHttpRequest();
var target = xhr.upload;
//进度
target.onprogress = function(ev){
    console.log(ev);
}
//成功
target.onload = function(){
    console.log('success');
}
//失败
target.onerror = function(){
    console.log('fail');
}
xhr.open("POST",'/upload',true);
xhr.send(file);

2.

const filterFiles = [...files].filter((el)=>{
    return el.size<=1024*1024;//1M
})

3.

const promise = function(file){
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        var target = xhr.upload;
        target.onloadend = function(){
            //console.log('complete');
            resolve();
        }
        target.onerror = function(){
            //fail
            reject();
        }
        xhr.open("POST",'/upload',true);
        xhr.send(file);
    });
}

const promises = [...files].map(function(file){
    return promise(file);
})

Promise.all(promises).then(function(values) {
    //console.log('all complete');
});

@Despair-lj
Copy link

Despair-lj commented Aug 14, 2019

// 1
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(event) {
  if (event.lengthComputable) {
    console.log(`上传进度为: ${event.loaded} of ${event.total} bytes`);
  }
};
xhr.onload = function() {
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
    console.log('成功 ' + xhr.responseText);
  } else {
    console.warn('失败 ' + xhr.status);
  }
};
xhr.onerror = function() {};
xhr.open('POST', '/upload', true);
xhr.send(file);

// 2

const finalFiles = [];
const fileMaxSize = 1024 * 1024;
Array.from(files).forEach(
  file => file.size < fileMaxSize && finalFiles.push(file)
);

// 3
function setPromise(file) {
  return new Promise(function(resolve) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
      resolve(true);
    };
    xhr.onerror = function() {
      resolve(false);
    };

    xhr.open('POST', '/upload', true);
    xhr.send(file);
  });
}

const filePromise = Array.from(files).map(file => setPromise(file));
Promise.all(filePromise).then(function(res) {
  res.forEach(r => {
    if (r) {
      console.log('上传成功');
    } else {
      console.log('上传失败');
    }
  });
});

@GitHdu
Copy link

GitHdu commented Aug 14, 2019

var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function () {}
xhr.upload.onload = function () {}
xhr.upload.onerror = function () {}
xhr.open('post','/post',true)
xhr.send(file)
Array.from(files).filter((file)=>{
    return file.size/1024/1024 <= 1
})
function promisify(file) {
  return new Promise(function(resolve,reject) {
    var xhr = new XMLHttpRequest().upload;
    xhr.onload = function() {
      resolve(true);
    };
    xhr.onerror = function() {
      reject(false);
    };

    xhr.open('POST', '/upload', true);
    xhr.send(file);
  });
}
Promise.all(Array.from(files).map((file)=>{return promisify(file)})).then(res=>{
  // uploaded
}).catch(err => {
  // error
})

@livetune
Copy link

livetune commented Aug 14, 2019

第一题

var xhr = new XMLHttpRequest()
// 进度
xhr.onprogress = () => { }
// 失败
xhr.onerror = () => { }
// 成功
xhr.onload = () => { }
xhr.open('POST', '/upload', ture)
xhr.send()

第二题、第三题

let { files } = document.querySelector('[type=file]')
files = [...files].filter(v => v.size <= 1024 * 1024)
console.log(files)
uploadFiles(files).then(res => { console.log(res) }).catch(err => {
    console.log(err)
})
function uploadFiles(files) {
    return Promise.all(files.map(uploadFile))
}
function uploadFile(file) {
    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest()
        const formData = new FormData(file)
        // 失败
        xhr.onerror = () => reject({ status: xhr.statusText, data: xhr.responseText })
        // 成功
        xhr.onload = () => resolve({ status: xhr.statusText, data: xhr.responseText })
        xhr.open('POST', '/upload', ture)
        xhr.send(formData)
    })
}

@ziven27
Copy link

ziven27 commented Aug 14, 2019

第一题

这个 API 没有实际使用经验,查阅的 MDN

var xhr = new XMLHttpRequest();
xhr.open("POST", "/upload", true);
xhr.onerror = function (e) {
	console.log('失败');
};
xhr.onprogress = function (e) {
	var progress = Math.round(e.loaded / e.total * 100);
	console.log('当前上传进度' + progress + "%");
};
xhr.onload = function () {
	if (xhr.status == 200) {
		console.log('成功');
	} else {
		console.log('失败');
	}
};
xhr.send(file);

第二题

const newFiles= Object.values(files).filter((file)=>file.size < 1024*1024 );

第三题

这道题没有思路

@guqianfeng
Copy link

    let xhr = new XMLHttpRequest();
    xhr.upload.onporgress = function(event){
        //event.loaded 加载了多少 event.total总共多少
    };
    xhr.onload = function(){

    };
    xhr.onerror = function(){

    };
    xhr.open("POST", "upload", true);
    xhr.send(file);
    let resultFile = [...files].filter(item => item.size <= 1024 * 1024);
    function uploadPromise(file){
        //返回promise对象,Promise.all语法传入的数组元素都是Promise对象
        return new Promise((resolve, reject)=>{
            let xhr = new XMLHttpRequest();
            xhr.onload = function(){
                resolve();
            };
            xhr.onerror = function(){
                reject();
            };
            xhr.open("POST", "upload", true);
            xhr.send(file);
        })
    }

    Promise.all(resultFile.map(file => uploadPromise(file))).then(()=>{
        //所有的都上传结束了
    })

@NeilChen4698
Copy link

xhr.onprogress = function() {
  //
}
xhr.onload = function() {
  //
}
xhr.onerror = function() {
  //
}
[].filter.call(files, function(ele) {
	return ele.size <= 1024 * 1024;
});
Promise.all([].map.call(files, function(file) {
  return new Promise(function(resolve) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
      resolve();
    }
    xhr.onerror = function() {
      resolve();
    }
    xhr.open('POST', '/upload', true);
    xhr.send(file);
  });
})).then(function() {
  console.log('all finished');
});

@Seasonley
Copy link

//1
xhr.addEventListener('progress', handleEvent);
xhr.addEventListener('load', handleEvent);
xhr.addEventListener('error', handleEvent);
//2
function fileFilter(files){
    return files.map(file=>file.size/2**20)
}
//3
Promise.all(files.map(v=>requestPromise("POST",'/upload',v)))
.then((values)=>{
    console.log(values);
});
//
function requestPromise(method, url,file) {
    return new Promise(function (resolve) {
        var xhr = new XMLHttpRequest()
        xhr.open(method, url,true)
        xhr.onload = function () {
        if (this.status >= 200 && this.status < 300)
            resolve(xhr.response)
        else
            resolve({status: this.status,statusText: xhr.statusText})
        }
        xhr.onerror = function () {
            resolve({status: this.status,statusText: xhr.statusText})
        }
        xhr.send(file)
    })
}

@JaimeCheng
Copy link

// 1
xhr.upload.onprogress = function (e) { }
xhr.onload = function (e) { }
xhr.onerror =  function (e) { }

// 2
var filterFiles = [...files].filter(file => file.size < 1024*1024*1)

// 3 
// I have no idea ╥﹏╥...

@Forx-Js
Copy link

Forx-Js commented Aug 15, 2019

  1. 使用onreadystatechange readyState === 4 来判断完成,使用statusText==='OK'判断是否成功
xhr.onreadystatechange = ({
  currentTarget,
  currentTarget: {
    readyState,
    response,
    statusText
  }
}) => {
  if (readyState === 4) {
    if (statusText.toLocaleLowerCase() === 'ok') {
      console.log('成功');
    } else {
      console.log('失败');
    }
  }
};
// 进度
 xhr.upload.onprogress = (e) => console.log('上传中');
  1. 只留下大于1M的文件
//zxx: 这里反了哟,应该留下小于1M的
const fileFilter = Array.prototype.filter.call(files, file => ~~(file.size / 1024 / 1024)
  1. Promise和Promise.all
const uploadXhrList = fileFilter.map(
  (file) => new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    /* ... 代码 
    成功时
    */
    resolve();
    /* ... 代码 
      失败时
    */
    reject();
    /* ...代码 */
  })

)
Promise.all(uploadXhrList).then(() => {
  /*统一处理*/
})

@WGHwebitem
Copy link

WGHwebitem commented Aug 15, 2019

<input type="file" id="file"  multiple="multiple" />
1
	var xhr =new XMLHttpRequest();
	//进度
	xhr.upload.addEventListener('progress',function(event){
		console.log(event)
	})
	//成功
	xhr.upload.addEventListener('load',function(event){
		console.log(event)
	})
	//失败
	xhr.upload.addEventListener('error',function(event){
		console.log(event)
	})
	xhr.open('POST','/upload',true);
	xhr.send(file);
	
	2
	var fileid=document.getElementById('file');
	fileid.onchange=function(){
		var fileSize=0;
		var fileMaxSize=1024;
		var filePath=this.value;
		if(filePath){
			fileSize=this.files[0].size;
			var size = fileSize/1024/1024;//1M
			if(size>1){
				alert("文件大小不能大于1M!");
	            fileid.value = "";	
			}
		}else{
			return false;
		}
	}	
   3
	function loadAsk(){
		var xhr =new XMLHttpRequest();
		xhr.onreadystatechange=function(){
			if(xhr.readyState==4 && xhr.status==200){
				document.getElementById('odiv').innerHTML=xhr.responseText;
			}else{
				alert('');
			}
		}
		xhr.open('POST','/upload',true);
	    xhr.send();
	}

@les-lee
Copy link

les-lee commented Aug 15, 2019

1.

var xhr = new XMLHttpRequest();
var uploadTarget = xhr.upload;
// 进度
uploadTarget.onprogress = function (ev) {
}
//成功
uploadTarget.onload = function (e) {
}
//失败
uploadTarget.onerror = function (e) {
}
xhr.open("POST", '/address', true);
xhr.send(file);

2.

let bigger_one_file = [...files].filter(files => {
  return files.size / 1024 / 1024 < 1;
})


3.

// 第一种是次数统计, 成功或者失败都累加, 当提交次数与提交成功次数重合便可以认为是所有图片都上传成功
let uploadLength = 0
function uploadImage(file) {
  var xhr = new XMLHttpRequest();
  var uploadTarget = xhr.upload;
  //成功
  uploadTarget.onload = function (e) {
    uploadLength++
    if (uploadLength === files.length) {
      // all done
    }
  }
  //失败
  uploadTarget.onerror = function () {
    uploadLength++
    if (uploadLength === files.length) {
      // all done
    }
  }
  xhr.open("POST", '/address', true);
  xhr.send(file);
}

files.forEach(file => uploadImage(file))



// 第二种是想到了 promise.all() 不过all 有一个缺点就是一个失败, 就会停止, 此时可以使用 Promise.allSettled() 这个比较新,这个跟all差不多不过他就算有promise失败了也是不会停止的。不过可能兼容性没那么好

function uploadImage(file) {
  return new Promise(function (resolve, reject) {
    let xhr = new XMLHttpRequest();
    let uploadTarget = xhr.upload;
    //成功
    uploadTarget.onload = function (e) {
      resolve('success')
    }
    //失败
    uploadTarget.onerror = function () {
      reject('fail')
    }
    xhr.open("POST", '/address', true);
    xhr.send(file);
  })
}

Promise.allSettled(files.map(file => uploadImage(file))).then((results) => {
  results.forEach((result) => console.log(result.status))
  console.log('all done')
})

// 第三种就是使用 一条 promise 去按顺序的进行提交, 直到提交完成,不过需要借助 generator 函数, 比较绕,而且并不是一种好的解法, 因为太慢。。。
// 这里就不再展述了。。。

@wingmeng
Copy link

第 1 题:

var xhr = new XMLHttpRequest();

// 上传进度(监听 upload 的 onprogress 事件)
xhr.upload.onprogress = function(e) {
  var percent = e.loaded / e.total * 100
  console.log('上传进度:' + percent + '%');
}

// 请求完成
xhr.onload = function() {
  var resOK = 200;
  console.log('请求完成');

  // 一个完成的请求不一定是成功的请求,故需要判断状态码来确认
  if (xhr.status === resOK) {
    console.log('请求成功')
  }
}

// 请求错误
xhr.onerror = function() {
  console.log('请求失败')
}

xhr.open('POST', '/upload', true);
xhr.send(file);

第 2 题:

var maxFileSize = 1 * (1024 * 1024);  // 1MB

files = [].slice.call(files).filter(function(file) {
  return file.size <= maxFileSize
});

第 3 题:

这里用 Promise.all 方法无疑是最合适的,但看题目中的 js 代码没有使用 ES6+,所以这里用 ES5 规范来实现:

// 这里的 files 是第 2 题中处理过的 files
files.map(uploadImg);

function uploadImg(img) {
  var xhr = new XMLHttpRequest();

  xhr.onload = function() {
    var resOK = 200;

    if (xhr.status === resOK) {
      img._uploaded = true
    }
  }

  xhr.onerror = function() {
    img._uploaded = false
  }

  // 请求结束(无论成功与否)
  xhr.onloadend = checkUpload;

  xhr.open('POST', '/upload', true);
  xhr.send(img);
}

function checkUpload() {
  var isDone = files.every(function(file) {
    return file.hasOwnProperty(_uploaded)
  });

  if (isDone) {
    console.log('上传已结束');

    var result = files.reduce(function(count, cur) {
      count[cur._uploaded ? 'success' : 'fail'] += 1;
      return count;
    }, {
      success: 0,
      fail: 0
    });

    console.log('上传结果:' +
      '成功' + result.success + '个' +
      '失败' + result.fail + '个'
    );

    if (result.success === files.length) {
      console.log('图片全部上传成功')
    }
  }
}

@asyncguo
Copy link

xhr.addEventListener('progress', function (e) {
}, false)
xhr.addEventListener('load', function (e) {
}, false)
xhr.addEventListener('error', function (e) {
}, false)
[...files].filter(item => item.size <= 1 * 1024 * 1024)
function uploadPromise (file) {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest()
  
    xhr.addEventListener('progress', function (e) {
    }, false)
    xhr.addEventListener('load', function (e) {
      resolve('success')
    }, false)
    xhr.addEventListener('error', function (e) {
      resolve('error')
    }, false)

    xhr.open('POST', '/upload', true)
    xhr.send(file)
  })
}
let xhrArr = []
[...files].map(file => {
  xhrArr.push(uploadPromise(file))
})

Promise.all(xhrArr).then(res => {
}).catch(error => {
})

@juzhiqiang
Copy link

第一题
上传进度监听
 xhr.upload.addEventListener('progress', function(){}, false);
成功
xhr.addEventListener("load", function(){}, false);
失败
xhr.addEventListener("error", function(){}, false);

第二题
       方法一
       for (let i = 0, i< files.length;i++) {
           if (files[i].size <= 1 * 1024 * 1024) {
                 //小于1M的文件操作在这块
           }
       }

     方法二
        let  filterFiles = [...files].filter(file =>  file.size <= 1*1024*1024);

第三题
      思路是在全局给个计数变量 
      然后再ajax请求内无论是成功还是失败回来就+1 统计最后总数与上传总数相等 则全部上传完成  
           
         
 

@ghost
Copy link

ghost commented Aug 15, 2019

1

const xhr = new XMLHttpRequest()
const listen = xhr.upload.addEventListener.bind(xhr.upload)
// 进度
listen('progress', (event) => {
    if (event.lengthComputable) {
        let p = event.loaded / event.total
        console.log('upload percentage', p)
    }
})
// 成功
listen('load', () => {
    console.log('upload success')
})
// 失败
listen('error', () => {
    console.log('upload fail')
})

xhr.open('post', '/upload', true)
xhr.send(file)

2

const filtered = [...files].filter((file) => file.size <= 1024 * 1024)

3

const ajaxUpload = (file, endFunc) => {
    const xhr = new XMLHttpRequest()
    const listen = xhr.upload.addEventListener.bind(xhr.upload)
    // 进度
    listen('progress', (event) => {
        if (event.lengthComputable) {
            let p = event.loaded / event.total
            console.log('upload percentage', p)
        }
    })
    // 成功
    listen('load', () => {
        console.log('upload success')
    })
    // 失败
    listen('error', () => {
        console.log('upload fail')
    })
    // 完成(无论成功或失败)
    listen('loadend', endFunc)

    xhr.open('post', '/upload', true)
    xhr.send(file)
}

let length = files.length
const endFunc = () => {
    length -= 1
    if (length === 0) {
        console.log('all done')
    } else {
        console.log(`${length} file uploading`)
    }
}
for (let i = 0; i < length; i++) {
    let file = files[i]
    ajaxUpload(file, endFunc)
}

@sghweb
Copy link

sghweb commented Aug 15, 2019

// 第一题
// 进度
function updateProgress(e) {}
// 成功
function transferComplete(e) {}
// 失败
function transferFailed(e) {}
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", updateProgress);
xhr.upload.addEventListener("load", transferComplete);
xhr.upload.addEventListener("error", transferFailed);
xhr.open("POST", '/upload', true)
xhr.send(file)

// 第二题
let input = document.querySelector('input')
input.onchange = function(e) {
  console.log(this.files)
  let arr = [...this.files]
  let files = arr.filter(item => {
    return item.size <= 1024 * 1024
  })
  console.log(files)
}

// 第三题
// 初始化一个计数器为count为0,在成功和失败里进行加加,只要count值和files的length一样表示上传结束

@xxf1996
Copy link

xxf1996 commented Aug 15, 2019

只写了逻辑代码,并没有写完整的;

// 第一题
let xhr = new XMLHttpRequest()
xhr.onprogress = e => { // 进度
  // ...
}
xhr.onerror = e => { // 失败
  // ...
}
xhr.onload = e => { // 成功
  // ...
}

// 第二题
let fileList = Array.from(files).filter(file => file.size <= 1024 * 1024)

// 第三题
function uploadImage (file) {
  let xhr = new XMLHttpRequest()
  // ...
  return new Promise((resolve, reject) => {
    xhr.onerror = e => {
      resolve()
    }
    xhr.onload = e => {
      resolve()
    }
  })
}
Promise.all(fileList.map(file => uploadImage(file))).then(() => { // 所有图片上传结束后
  // ...
})

@theDrunkFish
Copy link

题目1

var xhr = new XMLHttpRequest();
var upload = xhr.upload;
// 进度
upload.addEventListener('progress', progressHandle, false);

// 成功
upload.addEventListener('load', loadHandle, false);

// 失败
upload.addEventListener('error', errorHandle, false);

xhr.open('POST', '/upload', true);
xhr.send(file);

题目2

var canUploadFiles = [].filter.call(files, function(file){
    return file.size <= 1024 * 1024;
})

题目3(不会)

@fzpijl
Copy link

fzpijl commented Aug 15, 2019

xhr.upload.onprogress = function() {}
xhr.onreadystatechange = function() {
    if(xhr.readystate === 4) {
        if((xhr.status>= 200 && xhr.status < 300) || xhr.status === 304) {}
    }
}
xhr.onerror = function() {}
var oneM = 1024 * 1024;
files = files.filter(file => file.size <= oneM)

3.不会了

@silverWolf818
Copy link

//第一题
var xhr = new XMLHttpRequest();
xhr.onerror = function(){};
xhr.onprogress = function(){};
xhr.onload = function(){};

//第二,三题
document.querySelector('input[type=file]').addEventListener('change',function (e) {
   const files = Array.from(e.target.files).filter(item => {
       return item.size/1024/1024 < 1
   });
    //整体思路就是用计算器来计算成功和失败等于文件总个数。
    var len = files.length;
    var i = 0;
    files.forEach(item => {
        //
        const xhr = new XMLHttpRequest();
        xhr.onload = function(){
            i++;
        };
        xhr.onerror = function(){
            i++;
        };
        xhr.onloadend = function () {
            if(len === i){
                console.log("加载完毕")
            }
        }
    });
},false);

@zy017
Copy link

zy017 commented Aug 16, 2019

// 1. 
var xhr = new XMLHttpRequest();
var xhrUpload = xhr.upload;

xhrUpload.addEventListener("progress", function(e){});
xhrUpload.addEventListener("load", function(e){});
xhrUpload.addEventListener("error", function(e){});

xhr.open("POST", '/upload', true);
xhr.send(file);

// 2.
function filterFile(files) {
    return [...files].filter(file => file.size / 1024 /1024 <= 1 )
}
var { files } = document.querySelector('input[type=file]')
var filesFilter = filterFile(files)

// 3.
var uploadPromise = function(file) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest()
        var xhrUpload = xhr.upload
        xhrUpload.addEventListener("progress", function(e){});
        xhrUpload.addEventListener("load", function(e){
            // resolve()
        });
        xhrUpload.addEventListener("error", function(e){
            reject()
        });
        xhrUpload.addEventListener("loadend", function(e){
            resolve()
        });
        xhr.open("POST", '/upload', true);
        xhr.send(file)
    })
}

Promise.all(filesFilter.map(file => uploadPromise(file))).then(values => { 
    console.log(values)
})

@liyongleihf2006
Copy link
Contributor

这阵子工作有些忙直到现在才有时间来做作业,回答的有些靠后了

第一题

var xhr = new XMLHttpRequest();
//进度
xhr.addEventListener("progress", function (evt) {}, false);
//成功
xhr.addEventListener("load", function (evt) {}, false);
//失败
xhr.addEventListener("error", function (evt) {}, false);
//取消,问题中没有取消,但我顺带也把取消写上吧
xhr.addEventListener("abort", function (evt) {}, false);
//超时,问题中没有超时,但我顺带也把超时写上吧
xhr.addEventListener("timeout", function (evt) {}, false);

xhr.open("POST", '/upload', true);
xhr.send(file);

第二题

//过滤掉大于1M的,所以1M的不能被过滤掉,所以是<=
[...files].filter((file) => file.size <= 1024 * 1024)

第三题

const ajaxPromise = function (file) {
    return new Promise(function (resolve) {
        var xhr = new XMLHttpRequest();

        //成功与失败都触发
        xhr.addEventListener("loadend", function (evt) {
            resolve();
        }, false);

        xhr.open("POST", '/upload', true);
        xhr.send(file);
    });
}

async function uploadCompletes (files) {
    const ajaxPromises = [...files].map(function (file) {
        return ajaxPromise(file);
    })
    for (let i = 0, len = ajaxPromises.length; i < len; i++) {
        await ajaxPromises[i];
    }
}

uploadCompletes(files).finally(function(){
  console.log("上传结束了");
})

@frankyeyq
Copy link

frankyeyq commented Aug 16, 2019

1. 
// 进度
xhr.addEventListener('progress', function() {

});
// 成功
xhr.addEventListener('load', function() {

});
// 失败
xhr.addEventListener('error', function() {

});
2. 
files = Array.from(files).filter(file => file.size <= 1024 * 1024)
3.
function uploadFile(file) {
    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest();
        xhr.onloadend = function() {
            resolve();
        }
        xhr.open("POST", '/upload', true);
        xhr.send(file);
    });
}
var promises = files.map(uploadFile)
Promise.all(promises).then(res => {
    // 所有的上传都结束了
})

@lifelikejuly
Copy link

  • 第一题
xhr.upload.addEventListener("load", successFunc);//成功
xhr.upload.addEventListener("error", errorFunc);//失败
xhr.open("POST",'/upload',true);
xhr.send(file);
  • 第二题
var smallFiles = Array.from(files).filter((file) => {
    return file.size <= 1024 * 1024;
});
  • 第三题
function multipleUpload(file){
    return new Promise(function(resolve,reject){
        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("load", ()=>{
            resolve(true);
        });//成功
        xhr.upload.addEventListener("error", ()=>{
            reject(false);
        });//失败
        xhr.open("POST",'/upload',true);
        xhr.send(file);
    });
}

Promise.all(Array.from(files).filter((file) => {
    return multipleUpload(file);
})).then(res =>{
    //成功
}).catch(
    error =>{
        //失败
    }
);

@bugaosunihhh
Copy link

bugaosunihhh commented Aug 16, 2019

第一题

var xhr = new XMLHttpRequest();
var upload = xhr.upload;
upload.onprogress = function(){

};
upload.onload = function(){
    
};
upload.onerror = function(){
    
};

xhr.open();
xhr.send();

第二题

<input type="file" multiple id="files">
<script type="text/javascript">
    document.querySelector("#files").addEventListener("change", function(e){
        let target = e.target;
        let files = target.files;
        // 通过判断 files 里的 size 属性进行过滤;
        let filterFiles = [...files].filter( file => {
            return file.size < 1024*1024;
        });
    })
</script>

第三题

多张上传,有一张上传失败就算结束

var upload = function(file){}{
    return new Promise (resolve, reject){
        var xhr = new XMLHttpRequest();
        var upload = xhr.upload;
        upload.onload = function(){
            resolve()
        };
        upload.onerror = function(){
            reject()
        };
        xhr.open('xxx');
        xhr.send(file);
    }
}

// 只要有一个上传失败,就会catch
Promise.all(filterFiles.map( file => upload(file))).then(res=>{

}).catch(res=>{

})

多张上传,全部结束,不管单张的成功与否

var upload = function(file){}{
    return new Promise (resolve, reject){
        var xhr = new XMLHttpRequest();
        var upload = xhr.upload;
        upload.onload = function(){
            resolve('success')
        };
        upload.onerror = function(){
            resolve('fail')
        };
        xhr.open('xxx');
        xhr.send(file);
    }
}

Promise.all(filterFiles.map( file => upload(file))).then( res =>{
    console.log("全部上传结束");
    var success = res.filter( item => item === 'success' ).length;
    var fail = res.filter( item => item === 'fail' ).length;
    console.log(success+'张成功,'+fail+'失败')
}).catch(res=>{
    console.log("其他错误")
})

@zengqingxiao
Copy link

zengqingxiao commented Aug 16, 2019

第一题

    var xhr = new XMLHttpRequest();
    var upload = xhr.upload;
    if (xhr) {
      upload.onprogress = function () { console.log('进度') }
      console.log('进度')
      xhr.open("POST", "/upload", true);//get类型、url、是否异步
      xhr.onreadystatechange = function () {//服务器返回响应时触发
        if (xhr.readyState == 4 && xhr.status == 200) {//返回的类型
          try {
            upload.onload = function () { console.log('获取成功') }
          } catch {
            console.log('运行失败')
          }

        } else {
          upload.onerror = function () { console.log('访问服务器失败') }
        }
      };

      xhr.send(file);
    } else {
      alert("不支持XMLHttpRequest");
    }

第二题

    const newFiles = [].slice.call(files);
    const fileArr = newFiles.filter((item) => {
      return item.size / 1024 / 1024 < 1;
    })

第三题

Promise.all().then(() => { console.log('所有图片上传成功') })

@GCGligoudan
Copy link

GCGligoudan commented Aug 16, 2019

// 第一题
// 进度
xhr.onprogress = function() {
}
// 成功
xhr.onload = function() {
  if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304 ) {
    // 表示请求成功
  }
}
// 表示失败
xhr.onerror = function() {
}

// 第二题
var files = document.querySelector(input[type='file']).files;
[...files].filter((file) => {
  return file.size < 1024 *1024 * 1;
})

// 第三题
var count = 0;
// 对获取到的每个文件进行上传
// 监听上传成功或失败
xhr.onload = function() {
  count ++;
  isFinished(count);
}
xhr.onerror = function() {
  count ++;
  isFinished(count);
}
function isFinished(count) {
  if (count === files.length){
    // 所有的请求已经结束
  }
}

@kuikuiGe
Copy link

//1.

xhr.upload.onprogress = function(event){
    if(event.lengthComputable){
        console.log('上传进度:'+event.loaded+'/'+event.total)
    }
}

xhr.onreadystatechange = function(event){
    if (xhr.readyState == 4) {
        if (xhr.status == 200) {
            console.log("上传成功")
        }else{
            console.log("上传失败")
        }
    }
}

//2.

var filterFiles = [].slice.call(files).filter(file=>{
    return file.size > 1 * 1024 * 1024
})

//3.

var filterFiles = [],
    currFiles = [];

document.getElementById("test").onchange = function(){
    var files = document.getElementById('test').files;

    filterFiles = [].slice.call(files).filter(file=>{
        return file.size > 1 * 1024 * 1024
    })

    currFiles = filterFiles

    for(var i=0;i<filterFiles.length;i++){
        (function(file){
            uploadFile(file)
        }(filterFiles[i]))
    }
}

function deleteFile(files,file){
    var result = [];
    for(var i=0;i<files.length;i++){
        if(files[i] != file){
            result.push(files[i])
        }
    }     

    return result
}

function uploadFile(file){
    var formData = new FormData()

    formData.append('file',file)

    var xhr = new XMLHttpRequest();
    
    xhr.upload.onprogress = function(event){
        if(event.lengthComputable){
            console.log(file.name+'进度条:'+event.loaded+'/'+event.total)
        }
    }

    xhr.onreadystatechange = function(event){
        if (xhr.readyState == 4) {
            currFiles = deleteFile(currFiles,file)
            if (currFiles.length==0){
                console.log("所有图片都上传结束")
            }
        }
    }

    xhr.open('POST','/upload',true)
    xhr.send(formData)
}

@zhangxinxu
Copy link
Owner Author

zhangxinxu commented Aug 17, 2019

本期要点:

  1. xhr.onprogress和xhr.upload.onprogress的区别:这两个都能显示进度百分比,但是,前者显示的是服务器返回的数据,后者是发送给服务器的。例如,我们ajax get一张图片,则前者合适;如果我们是ajax post上传一张图片,则后者合适。
  2. event.target.files是一个选择文件对象类数组,适合使用filter进行过滤,然后文件大小直接file.size就有,file.name是文件名。
  3. onloadend回调,这个成功和失败都会触发。Promise.all是比较好的方法,但是有兼容性。
    xhr.onerror = function() { resolve(false); } 不推荐,xhr.onerror = function() { reject(false); } + Promise.all则是有问题,会中断,可以使用Promise.allSettled() 这个比较新的特性。
  4. 传统的计数器实现,每完成一个loadend,则计数变化一位,直到和files.length匹配。
  5. 小礼物。GMTC全球大前端技术大会现场演讲视频(部分讲师不允许对外公布视频除外)兑换码,月底到期,突然想起来,送给大家。规则是:第一个在两个微信群发出:把你的微信昵称写在CSS世界任意一页,拍照发到群里,第一位小伙伴可以获得。

@tao1874
Copy link

tao1874 commented Aug 17, 2019

第一题

xhr.onprogress = function(event) {}
xhr.onload = function(event) {}
xhr.onerror = function(event) {}

第二题

const filterFiles = Array.from(this.files).filter( e => e.size < 1024 * 1024 )

第三题

const filterFiles = Array.from(this.files).filter(e => e.size < 1024 * 1024)
        const uploads = filterFiles.map(file => {
            return new Promise((resolve, reject) => {
                var xhr = new XMLHttpRequest()
                xhr.onload = function (event) {
                    resolve(event)
                }
                xhr.onerror = function (event) {
                    reject(event)
                }
                xhr.open("post", "./upload")
                xhr.send(file)
            })
        })
Promise.all(uploads).then(res => {
                console.log("ok")
        }).catch(err => {
                console.log("error")
            })
        })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests