小程序报错:
这个是因为 赋值出现的问题:
情况一:formData.value.certificates = [] 原来是一个数组,但是赋值了字符串:sampleItem.data.certificates(请求回来的字符串),而且用到了页面的表单数据上,所以报错了。
let sampleItem = await dengbaoNewsApi.getSampleItem(formData.value.sampleId)
formData.value.certificates = sampleItem.data.certificates
情况二:Promise 请求导致的 赋值问题
selectorTypeList = [{},{}] 这个数据的格式
下面是异步请求 selectorTypeList.value 的数据
const getgetSampleTypeList = async() => {
dengbaoNewsApi.getSampleType().then(res=>{
selectorTypeList.value = res.data.list.map(item=>{
return {
id: item.id,
type: item.name
}
})
console.log('请求的类型列表====',selectorTypeList.value)
})
}
在onLoad 中调用:
onLoad(async(options)=>{
await getgetSampleTypeList()
console.log('111=====',selectorTypeList.value)
这里的一些数据需要用到 selectorTypeList 数组中的值
...})
控制台输出结果:
问题:在于 getgetSampleTypeList
函数内部并没有正确返回 Promise 对象。实际上 getgetSampleTypeList
函数内部的异步操作并不会被正确等待完成,导致后续的代码可能会在异步操作完成前就开始执行。
解决:方法一:返回一个Promise,getgetSampleTypeList
函数返回一个Promise 对象,用await去等待他执行完成
修改下 getgetSampleTypeList
函数的代码,执行成功则放回一个
const getgetSampleTypeList = async() => {
return new Promise((resolve, reject) => {
dengbaoNewsApi.getSampleType().then(res=>{
selectorTypeList.value = res.data.list.map(item=>{
return {
id: item.id,
type: item.name
}
})
console.log('请求的类型列表====',selectorTypeList.value)
resolve(); // 异步操作成功,调用 resolve
}).catch(error => {
reject(error); // 异步操作失败,调用 reject
});
})
}
解析:返回的是一个 Promise 对象,它会等待 dengbaoNewsApi.getSampleType()
异步操作的结果完成后再决定是解析还是拒绝这个 Promise 对象
所以可以使用:await getgetSampleTypeList()去等待结果再执行下面的语句
控制台输出结果(正确):
方法2:下面的代码:onLoad里面的getgetSampleTypeList()前面要加 await ,
const getgetSampleTypeList = async () => {
let res = await dengbaoNewsApi.getSampleType();
selectorTypeList.value = res.data.list.map(item => {
return {
id: item.id,
type: item.name
};
});
console.log('请求的类型列表====', selectorTypeList.value);
};
onLoad(async (options) => {
await getgetSampleTypeList();
console.log('111=====', selectorTypeList.value);
});
或者改成下面的写法:await 等promise执行返回结果,再执行下面的语句
onLoad(async (options) => {
await dengbaoNewsApi.getSampleType().then(res=>{
sampleTypeList.value = res.data.list.map(item=>{
return {
id: item.id,
type: item.name
}
})
console.log('请求的类型列表---',sampleTypeList.value)
})
console.log('111=====', sampleTypeList.value);
});
onLoad(async (options) => {
await getgetSampleTypeList(); 这里的await必须加
console.log('111=====', selectorTypeList.value);
});
不加 await 的情况(进去onLoad函数中)解析:
getgetSampleTypeList()
被调用,这是一个异步函数,但它的调用是非阻塞的。getgetSampleTypeList()
内部会立即执行到await dengbaoNewsApi.getSampleType();
,并且在等待dengbaoNewsApi.getSampleType()
完成时,控制权会返回到onLoad
函数。console.log('111=====', selectorTypeList.value);
会被立即执行,因为getgetSampleTypeList()
还没有完成。- 之后,当
dengbaoNewsApi.getSampleType()
完成时,getgetSampleTypeList()
内部的代码会继续执行,并打印console.log('请求的类型列表====', selectorTypeList.value);
。
由于 console.log('111=====', selectorTypeList.value);
在 await
语句之前执行,所以它会比 console.log('请求的类型列表====', selectorTypeList.value);
更早输出。
以上这种方法也保证了能拿到selectorTypeList.value的数据,再执行下面的语句
控制台输出结果(正确):
总结:要正确使用Promise 处理数据 异步操作/微任务 ,先确保用到的数据要先获取到,再执行下面的语句,这也是在调用接口经常遇到的问题