在ES6中引入的promise、async、await,异步编程的好处最直观的就是:
- promise可以摆脱回调嵌套,使用then同步式开发
- 使用async/await避免链式的promise
- 它们是异步的执行,不过给了你同步编程的感觉
语法
Promise 在处理异步操作时很有用。
JavaScript 提供了一个辅助函数Promise.all(promisesArrayOrIterable)来同时并行处理多个 promise,并在单个聚合数组中获取结果。让我们看看它是如何工作的。
1. Promise.all()
Promise.all() 接受一组 promises(或通常是一个可迭代的)。该函数返回一个 promise:
const allPromise = Promise.all([promise1, promise2, ...]);
然后您可以使用 then-able 语法提取 Promise 解析的值:
allPromise.then(values => {
values; // [valueOfPromise1, valueOfPromise2, ...]
}).catch(error => {
error; // rejectReason of any first rejected promise
});
或 async/await语法:
try {
const values = await allPromise;
values; // [valueOfPromise1, valueOfPromise2, ...]
} catch (error) {
error; // rejectReason of any first rejected promise
}
2. 应用举例:并行异步上传多个文件,全部完成后再提交表单
// 开始上传文件队列,完成后再提交数据
uploadFileStack: function (files, folderId, params) {
// 上传队列 promise数组
let uploadStack = files.map(file => this.uploadFile(file, folderId));
// 异步等待全部上传完成
async function promiseAll(arry) {
return await Promise.all(arry);
}
// promiseAll返回的是上传后文件ID集合数组
promiseAll(uploadStack).then(res => {
let FileInfo = res.map(id => {
return {
relationCode: 'FileInfo',
relationId: id
};
});
params.FileInfo = params.FileInfo.concat(FileInfo);
this.submit(params);
}).catch(err => {
this.$message.error(err);
});
},
// 上传文件
uploadFile: function (file, folderId) {
return new Promise((resolve, reject) => {
// 文件开始上传
let formData = new FormData();
formData.append('file[0]', file);
formData.append('fullPath[0]', '');
formData.append('folderId', folderId);
this.$ajax({
type: 'upload',
url: '/fileCenter/file/upload',
data: formData
}).then(res => {
if (res.success) {
resolve(res.model[0]);
} else {
reject(res.message);
}
}).catch(() => {
reject('文件上传异常');
});
});
}
4. 结论
Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型),并且只返回一个Promise实例, 在then回调的结果是一个数组。then执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。
本文暂时没有评论,来添加一个吧(●'◡'●)