• Promise.all()的使用以及js处理机制


    本文涉及到的知识:

    1. Promise,all()的使用
    2. js处理机制
    3. reduce的用法
    4. map的用法
    5. 同步异步

    需求:

    一个页面中需要用到多个字典数据。用于下拉选项,同时,需要将其保存为json格式。以便于key,value的相互转换。

    data(){
        return{
            codeList:[]
        }
    },
        
    computed:{
        	confPropertyTypeOptions() {
                return this.codeList.length ? this.codeList[0].options : [];
            },
    
            configurationTypeOptions() {
                return this.codeList.length ? this.codeList[1].options : [];
            },
    },
        
    created(){
    		let codeType = ['confPropertyType', 'configurationType'];
            let arrTemp = [];
            let promiseList = codeType.map(type => getCode(type));
            Promise.all(promiseList)
                .then(res => {
                    // arrTemp = res.map(v => {
                    //     if (Array.isArray(v.data) && v.data.length > 0) {
                    //         const arr = v.data;
                    //         let json = {};
                    //         for (let i in v.data) {
                    //             let item = v.data[i];
                    //             json[item.ctCode] = item.ctName;
                    //         }
                    //         return {
                    //             options: arr,
                    //             json: json,
                    //         };
                    //     }
                    //     return { options: [], json: {} };
                    // });
    
                    arrTemp = res.reduce((prev, current) => {
                        if (
                            Array.isArray(current.data) &&
                            current.data.length > 0
                        ) {
                            const arr = current.data;
                            let json = {};
                            for (let i in current.data) {
                                let item = current.data[i];
                                json[item.ctCode] = item.ctName;
                            }
                            prev.push({
                                options: arr,
                                json: json,
                            });
                            return prev;
                        }
                    }, []);
                    this.codeList = arrTemp;
                })
                .catch(() => {
                    this.$message.error('查询类型失败');
                });
        }
    

    getCode(codetype)是一个post请求。通过字典类型获取字典数据。

    最开始是这么实现的:

    created() {
    	let codeType = ['confPropertyType', 'configurationType'];
        codeType.forEach(code => {
            getCode(code).then(res => {
                if (
                    Array.isArray(res.data) &&
                    res.data.length > 0
                ) {
                    const arr = res.data;
                    let json = {};
                    for (let i in res.data) {
                        let item = res.data[i];
                        json[item.ctCode] = item.ctName;
                    }
                    this.codeList.push({
                        options: arr,
                        json: json,
                    });  
                })
        })
    }
    

    坑1:然而初始化页面的时候报错:compute里边的options值获取不到。为什么呢?

    因为:compute属性里的this.codeList.length在第一次push的时候就不为0了,所以会报错。this.codeList.length此时的长度为1。

    优化后:

    用一个临时数组去保存一下请求拿到的值,等foreach完成后再去赋值给codeList变量。

    created() {
        let arrTemp = [];
    	let codeType = ['confPropertyType', 'configurationType'];
        codeType.forEach((code,index) => {
            getCode(code).then(res => {
                if (
                    Array.isArray(res.data) &&
                    res.data.length > 0
                ) {
                    const arr = res.data;
                    let json = {};
                    for (let i in res.data) {
                        let item = res.data[i];
                        json[item.ctCode] = item.ctName;
                    }
                    arrTemp.push({
                        options: arr,
                        json: json,
                    });  
                })
            if(index === codeType.length-1){
                this.codeList = arrTemp
            }
        })
    }
    

    坑2:然后还是报错,但是我们的思路是正确的,就是等两次请求完成后,再去处理这个结果。

    这里是因为getCode()是一个异步方法,这两次异步完成的时间是不确定的,有可能你的第一个getCode(异步)还没返回结果,forEach(同步)已经完事了。

    需要了解一下js的异步处理机制。你的代码是一行行往下执行的,然后遇到一个异步方法(或者异步块),程序会把这个异步放到一个异步队列中,程序继续顺序执行,同时,异步队列中的块也在执行。不过它什么时候结束,你并不知道。

    这是Promise方法就发挥作用了。如我们最开始的实现。

    let promiseList = codeType.map(type => getCode(type));

    这时的promiseList是一个拥有两个Promise对象元素的数组

    promiseList = [new Promise(),new Promise()]

    Promise.all(promiseList),这两个post请求完成后,在.then()中可以处理res数据。

    然后就是res.map()与res.reduce()的用法与区别了。

    reduce(handler,target)

    1.handler是一个方法 (prevent,current) => {return prevent}

    ​ prevent是我们处理后的结果,用于返回,

    ​ current是当前累加器的元素

    2.target是我们的目标结果,可以是array,string,obj等

    passion
  • 相关阅读:
    MyEclipse快捷键大全
    The type 'Microsoft.Office.Interop.Excel.ApplicationClass' has no constructors defined
    ‘Microsoft.Office.Interop.Excel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c’
    使用游标循环表的简单DEMO
    URL Records
    一步一步教你实现CTreeCtrl 自绘
    自绘按钮
    UDP文件传输的实现
    美化VC界面(用户登录界面)
    如何截取QQ密码和聊天内容、去掉QQ广告栏、添加QQ尾巴
  • 原文地址:https://www.cnblogs.com/youngniu/p/12983262.html
Copyright © 2020-2023  润新知