需求:一个页面中需要用到多个字典数据。用于下拉选项,同时,需要将其保存为json格式。以便于key,value的相互转换。记录在实现过程中踩的坑

Promise,all()的使用

js处理机制

reduce的用法

map的用法

同步异步

需求:

一个页面需要用到多个字典数据用于下拉选项,同时,需要将其保存为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等

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpysjf.html