问题场景:在第一个异步请求的then 方法中调用第二个异步请求 对第一个请求返回的数据结果进行处理 并打印
模拟两个异步请求场景:
mounted() {
this.getData1();
},
methods: {
// 模拟获取数据列表
getData1() {
new Promise((resolve) => {
//第一个请求返回的结果
resolve([1, 2, 3]);
}).then((res) => {
//对返回的结果进行字符串转换处理
for (let i = 0; i < 3; i++) {
var str = this.getData2(res[i]);
console.log("第"+i+"项", str);
}
});
},
// 对数据进行处理
getData2(num) {
//第二个异步请求
new Promise((resolve) => {
resolve(num + "");
}).then((res) => {
console.log(res);
return res;
});
},
},
预期打印结果
第0项 1
第1项 2
第2项 3
1
2
3
实际打印结果 请求成功的值打印出来了,但是并未赋值成功
第0项 undefined
第1项 undefined
第2项 undefined
1
2
3
在 getData2 我们明明 将 res return出来了 但为什么没有赋值呢?
根据打印的结果,开始以为是异步问题,导致for循环执行完毕 但是请求内数据还没返回 最终返回出来的是undefined
于是进行了以下修改,我们让每次都拿到结果在赋值,这样就保证了不会提前打印
// 模拟获取数据列表
getData1() {
new Promise((resolve) => {
resolve([1, 2, 3]);
}).then(async (res) => {
for (let i = 0; i < 3; i++) {
var str = await this.getData2(res[i]);
console.log("第" + i + "项", str);
}
});
},
最终打印结果
1
第0项 undefined
2
第1项 undefined
3
第2项 undefined
不出所料 结果还是undefined没赋值成功,写到这里我们确定了并不是请求过慢的问题,是 this.getData2(res[i]) 🦆根就没值
也就是说 getData2中的return并没有生效
那么为什么 getData2 中的return没有生效呢?
让我们看下代码
return的res去哪了?
我们修改 getData2方法如下 并打印结果
getData2(num) {
new Promise((resolve) => {
resolve(num + "");
})
.then((res) => {
console.log(res);
return "拿到" + res;
})
.then((res) => {
console.log(res);
});
},
1
第0项 undefined
拿到1
2
第1项 undefined
拿到2
3
第2项 undefined
拿到3
这次我们在第二个then中 拿到了第一个then中return的结果
由此肯定 then中的 return的结果 是接下来链式写法then中的resolved参数,让我们看下官方文档如何描述
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。
因此可以采用链式写法,即then方法后面再调用另一个then方法。
此时真相大白了,调用来调用去发现做了无用功,那应该如何将 getData2 的值赋予 str 呢? 我们将整个 getData2 整个Promise对象return出去
修改后如下
mounted() {
this.getData1();
},
methods: {
// 模拟获取数据列表
getData1() {
new Promise((resolve) => {
resolve([1, 2, 3]);
}).then(async (res) => {
for (let i = 0; i < 3; i++) {
var str = await this.getData2(res[i]);
console.log("第" + i + "项", str);
}
});
},
// 对数据进行处理
getData2(num) {
return new Promise((resolve) => {
resolve(num + "");
}).then((res) => {
console.log(res);
return "拿到" + res;
});
},
},
打印结果如下,问题解决
1
第0项 拿到1
2
第1项 拿到2
3
第2项 拿到3
最后提示:
如果不使用await
var str = this.getData2(res[i]);
str将是一个 Promise对象
通过async/await去操作得到的对Promise象,也就是说,要想获取到Promise.then的返回值,就必须利用await获取,要想使用await,就必须在函数前面加上async
补充:await 操作符用于等待一个 Promise 对象的结果,await Promise 对象 是 Promise对象 resolved的语法糖 这也就是最终await Promise 对象 是返回的值的原因(这点可以深入看一下ES6 的 Promise)。