关于promise的一个误区

情况是这样的,今天在做接口相关的任务中,为了拿到后台返回的数据进行页面的更新,使用了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函数结束之前运行,也就是在未来接取未来的值。

     感谢看完!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值