计算机系统应用教程网站

网站首页 > 技术文章 正文

Promise.all与async/await的应用

btikc 2024-09-18 08:35:15 技术文章 29 ℃ 0 评论

在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的是第一个抛出的错误信息。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表