美文网首页
promise.all 转载 作者:shellteo 链接:ht

promise.all 转载 作者:shellteo 链接:ht

作者: 糖醋里脊120625 | 来源:发表于2019-06-22 10:46 被阅读0次

    Promise.all(iterable) 方法指当所有在可迭代参数中的 promises 已完成,或者第一个传递的 promise(指 reject)失败时,返回 promise。iterable为可迭代对象,但是一般为数组。返回值也是一个Promise对象。
    需要明确的几点,Promise.all是并发执行的同时运行多个Promise对象,而且返回的Promise对象的参数是一个数组,数组中的各项也是可迭代对象执行的顺序返回

    Promise.race(iterable) 方法返回一个新的 promise,参数iterable中只要有一个promise对象”完成(resolve)”或”失败(reject)”,新的promise就会立刻”完成(resolve)”或者”失败(reject)”,并获得之前那个promise对象的返回值或者错误原因。所以只要iterable中有一个完成或者失败就立即返回一个promise对象。根据race这个单词为赛跑也能得出,最先到达的立即返回一个promise对象。

    根据上面的定义,我们采用的Promise.all方法来完成我们的需求。

    //存储promise对象的数组
    let promiseArr = [];
    //图片地址数组
    let imageList = [];
    //将图片地址的上传的promise对象加入到promiseArr
    for (let i = 0; i < imageList.length; i++) {
        let promise = new Promise((resolve, reject) => {
            //微信图片上传
            wx.uploadFile({
                url: 'https://xxx.xxx.xxx/api/uploadImage',
                filePath: imageList[i],
                name: 'file',
                success: function(res) {
                    //可以对res进行处理,然后resolve返回
                    resolve(res);
                },
                fail: function (error) {
                    reject(error);
                },
                complete: function (res) {
                },
            })
        });
        promiseArr.push(promise)
    }
    //Promise.all处理promiseArr数组中的每一个promise对象
    Promise.all(promiseArr).then((result) => {
        //对返回的result数组进行处理
    })
    复制代码
    

    三、微信小程序的问题

    在做微信小程序的图片上传功能,这边只能先上传图片,然后将图片名和地址以response返回。

    这里面我们就是用了promise.all方法但是有一个问题就是,promise.all是并发执行的,但是微信小程序一次只能并发10个请求。

    对于图片上传,可能需要一次上传超过10张图片,也就是一次并发超过10个请求,这样的话微信就会报错

    “WAService.js:4 uploadFile:fail createUploadTask:fail exceed max upload connection count 10”

    [图片上传失败...(image-9922ff-1561171559021)]

    四、顺序Promise执行处理

    因为Promise.all是同时运行多个promsie对象,所以对于这种并发的数量,小程序是有限制的,一次只能并发10个,所以如果想突破这种限制,可以进行顺序执行每个Promise。
    代码如下:

    //顺序处理函数
    function sequenceTasks(tasks) {
        //记录返回值
        function recordValue(results, value) {
            results.push(value);
            return results;
        }
        let pushValue = recordValue.bind(null, []);
        let promise = Promise.resolve();
        // 处理tasks数组中的每个函数对象
        for (let i = 0; i < tasks.length; i++) {
            let task = tasks[i];
            promise = promise.then(task).then(pushValue);
        }
        return promise;
    }
    
    //函数数组,每个函数的返回值是一个promise对象
    let promiseFuncArr = [];
    //图片地址数组
    let imageList = [];
    //将图片地址的上传的函数加入到promiseFuncArr数组中
    for (let i = 0; i < imageList.length; i++) {
        let promiseTemp = function(){
            return new Promise((resolve, reject) => {
                //微信图片上传
                wx.uploadFile({
                    url: 'https://xxx.xxx.xxx/api/uploadImage',
                    filePath: imageList[i],
                    name: 'file',
                    success: function(res) {
                        //可以对res进行处理,然后resolve返回
                        resolve(res);
                    },
                    fail: function (error) {
                        reject(error);
                    },
                    complete: function (res) {
                    },
                })
            });
        };
        promiseFuncArr.push(promiseTemp)
    }
    
    sequenceTasks(promiseFuncArr).then((result) => {
        //对返回的result数组进行处理
    });
    复制代码
    

    1.这里解释一下sequenceTasks函数的作用

    首先recordValue函数传入两个值,一个是results是返回的数组,另一个是value,value是传入的值,results.push(value);将每一个值push到results数组,然后再返回results数组。

    let pushValue = recordValue.bind(null, []);
    pushValue也是一个函数对象,将recordValue bind到一个[ ]数组中,第一个参数传null代表,不改变函数this的指向,所以pushValue得到就是一个function (value)的函数,参数传入value。

    promise = promise.then(task).then(pushValue);
    task是函数,函数返回promise对象,在我们这里就是上传图片函数,每一张图片上传都创建一个函数,then(pushValue),pushValue是function (value)的函数,value代表的就是图片上传之后的返回值,pushValue将返回值push到result数组中,依次执行,依次加入到result数组中,最后返回。就可以得到一个对象数组,数组中就是依次执行返回的结果。

    2. sequenceTasks也里面的for循环,也可以写成如下的reduce方式:

    function sequenceTasks(tasks) {
        //记录返回值
        function recordValue(results, value) {
            results.push(value);
            return results;
        }
        let pushValue = recordValue.bind(null, []);
        return tasks.reduce(function (promise, task) {
            return promise.then(task).then(pushValue);
        }, Promise.resolve());
    }
    

    作者:shellteo
    链接:https://juejin.im/post/59f149d7f265da432c231301
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

          本文标题:promise.all 转载 作者:shellteo 链接:ht

          本文链接:https://www.haomeiwen.com/subject/qdymqctx.html