情况是这样的,今天在做接口相关的任务中,为了拿到后台返回的数据进行页面的更新,使用了AXIOS的跨域请求,然后就陷入了找数据——找bug——改Bug——找数据的死循环,最后改的烦躁了就去查找相关API和资料,然后这个被淡淡遗忘的知识点就又蹦了出来:
首先看段代码:
sumbit() {
let that = this;
let data1 = null;
axios.get('/axios/server', {
params: {
key: value
}
}).then(value => {
data1 = value.data;
//数据在返回的Data选项里
return data1
})
}
let data2 = data1 * data1
console.log(data2);
只是复制的代码段,但是有一个致命的点就是拿不到data1的数值,导致报错,
后来仔细想了想,会不会是return 返回的位置错误呢,然后把return 写在了sumbit的最下方,结果还是一大片热闹的红色,
然后就改bug——写bug——改bug——写bug。。。。
好了,讲了一大段废话,看了一大段bug,下面回归正题:
根据红宝书(JavaScript高级程序设计(第4版))一书中第11章——【期约与异步函数】中,对期约基础——期约状态机的一段描述:
重要的是,期约的状态是私有的,不能直接通过JavaScript检测到。这主要是为了避免根据读取到的期约状态,以同步方式处理期约对象。另外,期约的状态也不能被外部的JavaScript代码修改。这与不能读取该状态的原因是一样的:期约故意将异步行为封装起来,从而隔离外部的同步代码。
摘录于JavaScript高级程序设计(第4版)李松峰 译版
大致意思本文作者理解为,为了避免程序员错误的将promise(期约)与其链式的产生结果(也就是.then后产生的新的promise函数)与后面的同步代码混写在一块,【特地】封装了一下,不让程序员用它的返回内容(同步的用),
为此,解决方法也在此提供了两种:
1. 如果你promise后的代码量较少,可以将代码写在.then的返回内容里面,相当于普通函数的回调效果,就像这样:
sumbit() {
let data1 = axios.get('/axios-server', {
params: {
key: value
}
}).then(value => {
//余下所有代码写在这
})
}
2. 如果你promise后面的代码量比较大也比较杂,逻辑和功能比较多的情况可以使用async/await来解决,就像这样:
async sumbit() {
let data1 = await axios.get('/axios-server', {
params: {
key: value
}
})
return data1
}
async/await 用法如同字面意思所讲,待await后的代码块结束后再运行下方代码,以本文作者的理解就是 异异得同,方法本身是指异步函数,promise也算是简易的异步,他俩套一起却能以同步的方式运行代码,并且能够在promise外的代码拿到promise或.then的返回值,也就是实现了刚开始我们想要的需求。
下面是一些作者个人的总结:
问题: 外面的代码能不能拿到promise(期约)体里的数据?
答:不能,返回结果可能会是:null , undefind , 空白,或者报错
### 关于promise对象的值问题
1. 首先,promise里面的this指向可能会变,所以最好先指定一个that在外面接收你想要的的this
2. promise.then链式是执行回调,也就是说返回结果可能会被降低,或者说promise后面的代码想要使用promise或者then里面的变量或数据的话会显示空,null , undefind,也就是所谓的没办法在现在接取未来的值
3. 想要使用这些值最好用async/await异步操作,或者后期代码写在.then的链式里面
```
sumbit() {
let data1 = axios.get('/axios-server', {
params: {
key: value
}
}).then(value => {
//余下所有代码写在这
})
}
```
也就是说,上面的方法sumbit(防止和submit混淆)里面只能写一个promise,除非后面的内容和它无关,因为promise返回的还是一个promise,哪怕它内部的代码量已经通过.then返回的很小了
### 如果既想要用promise ,又想要返回值,可以通过 async/await语法
```
async sumbit() {
let data1 = await axios.get('/axios-server', {
params: {
key: value
}
})
return data1
}
```
道理就是async会等待promise函数完成后再执行后方代码,而不会出现后面代码会提前在promise函数结束之前运行,也就是在未来接取未来的值。
感谢看完!