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等