异步函数与Console的坑

在项目开发中遇见一个问题,用的vue框架然后在 created() 生命钩子中进行接口调用然后赋值,赋值完后再直接 console.log 打印更新的值
结果发现这个值输出的还是初始值,但是输出 this 却发现里面的值已经更新

简单点说就是,我更新 data 的值在 createdconsole ,但是 console.log(this.a) 的值还是初始的,但是 console.log(this) 里面a的 值已经更新了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<body>
<div id="app"></div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
created() {
this.updateMsg()
console.log(this.message,this) // Hello Vue!
},
methods: {
updateMsg() {
// 假设这里是个axios
const updateMsg = new Promise(function (resolve, reject) {
resolve('update')
})
// 假设这里是调用了接口,res是接口返回的值
updateMsg.then(res => {
this.message = res
})
}
},
})
</script>

当时的代码差不多情况如图
是的我的想法就是在调完接口后输出内容看下(实际是想输出返回中的一个id看下)
但是却发现无论怎么输出,在 created 里输出的都是默认值(初始值)
后来经过讨论和实践找到了问题,因为 Promise 是一个异步函数,异步执行的,然后 created 是在页面刷新/首次加载时就运行了,
所以这里其实会先运行 console.log(this.message,this) 导致这里的值还没更新

我也通过以下代码证实了猜想

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<body>
<div id="app"></div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
created() {
this.updateMsg()
setTimeout(() => {
console.log(this.message,this) // update
}, true)
console.log(this.message,this) // Hello Vue!

},
methods: {
updateMsg() {
const updateMsg = new Promise(function (resolve, reject) {
resolve('update')
})
updateMsg.then(res => {
this.message = res
})
}
},
})
</script>

是的如果把 console 放到一个异步函数( setTimeout 也是一个异步函数)里,那么输出的值也会是正常的了