javascript - 请问遍历中穿插异步操作怎么处理

查看:79
本文介绍了javascript - 请问遍历中穿插异步操作怎么处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

下面代码是图片上传业务,有旧图也可以加新图,新图要压缩,是异步
代码描述

解决方案

很奇怪,你用的压缩图片的插件为什么会是异步的?

不过既然lrz这个压缩图片插件返回的是一个Promise,那何不用async + await来搞。使用同步的方式写异步代码最爽了,伪代码如下:


async forEachAllImages(images) {
    if (this.state.commodityId === undefined) {
        commodityId = data.success.data.data;
    } else {
        commodityId = this.state.commodityId;
    }
    
    for (let item of images) {
        if ('id' in item) {
            // 旧图片
            console.log('旧图片');
            configArr.push({
                method: 'POST',
                url: 'http://139.224.65.179:8080/api/modify_img',
                data: { id: item.id, img_path: item.path }
            });
            file = item.path;
            lineState = true;
        }else {
            // 新图片
            console.log('新图片');
            
            // 压缩图片插件  -- await 会等待这个lrz处理完成后才返回
            const rst = await lrz(item.file, {
                width: 750,
                height: 750,
                quality: 0.5
            })
            
            configArr.push({
                method: 'POST',
                url: 'http://139.224.65.179:8080/api/modify_img',
                data: { prod_info_id: commodityId, img_path: rst.base64 }
            });
            
            lineState = true;
        }
    }
    
    console.log(200, configArr)
    let makeRequest = (config) => axios(config);
    let requests = configArr.map(makeRequest);
    axios.all(requests);
    this.setState({
        isRenderAlert: true,
        alertData: {
            title: '保存成功!',
            ms: 1500,
            end: () => {
                this.props.history.replace('commodity-detail?id='+ commodityId);
            }
        }
    });
}

// 遍历并处理所有图片
forEachAllImages.call(this, this.state.validatorValue.images)

对了,上面是串行压缩的。如果要并行压缩,可以用Promise.all这样做:


async forEachAllImages(images) {
    if (this.state.commodityId === undefined) {
        commodityId = data.success.data.data;
    } else {
        commodityId = this.state.commodityId;
    }
    
    
    for (let item of images) {
        if ('id' in item) {
            // 旧图片
            console.log('旧图片');
            configArr.push({
                method: 'POST',
                url: 'http://139.224.65.179:8080/api/modify_img',
                data: { id: item.id, img_path: item.path }
            });
            file = item.path;
            lineState = true;
        }else {
            // 新图片
            console.log('新图片');
            
            // 压缩图片插件
            configArr.push(lrz(item.file, {
                width: 750,
                height: 750,
                quality: 0.5
            }).then(rst => ({
                method: 'POST',
                url: 'http://139.224.65.179:8080/api/modify_img',
                data: { prod_info_id: commodityId, img_path: rst.base64 }
            }));
            
            lineState = true;
        }
    }
    
    configArr = await Promise.all(configArr)
    
    console.log(200, configArr)
    let makeRequest = (config) => axios(config);
    let requests = configArr.map(makeRequest);
    axios.all(requests);
    this.setState({
        isRenderAlert: true,
        alertData: {
            title: '保存成功!',
            ms: 1500,
            end: () => {
                this.props.history.replace('commodity-detail?id='+ commodityId);
            }
        }
    });
}

// 遍历并处理所有图片
forEachAllImages.call(this, this.state.validatorValue.images)

当然,这个并行版本其实不用async + await也可以写得很简洁:


forEachAllImages(images) {
    if (this.state.commodityId === undefined) {
        commodityId = data.success.data.data;
    } else {
        commodityId = this.state.commodityId;
    }
    
    
    for (let item of images) {
        if ('id' in item) {
            // 旧图片
            console.log('旧图片');
            configArr.push({
                method: 'POST',
                url: 'http://139.224.65.179:8080/api/modify_img',
                data: { id: item.id, img_path: item.path }
            });
            file = item.path;
            lineState = true;
        }else {
            // 新图片
            console.log('新图片');
            
            // 压缩图片插件
            configArr.push(lrz(item.file, {
                width: 750,
                height: 750,
                quality: 0.5
            }).then(rst => ({
                method: 'POST',
                url: 'http://139.224.65.179:8080/api/modify_img',
                data: { prod_info_id: commodityId, img_path: rst.base64 }
            }));
            
            lineState = true;
        }
    }
    
    Promise.all(configArr)
        .then(configArr => {
            console.log(200, configArr)
            let makeRequest = (config) => axios(config);
            let requests = configArr.map(makeRequest);
            axios.all(requests);
            this.setState({
                isRenderAlert: true,
                alertData: {
                    title: '保存成功!',
                    ms: 1500,
                    end: () => {
                        this.props.history.replace('commodity-detail?id='+ commodityId);
                    }
                }
            });
        });
}

// 遍历并处理所有图片
forEachAllImages.call(this, this.state.validatorValue.images)

三个版本任君挑选。

这篇关于javascript - 请问遍历中穿插异步操作怎么处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆