Js 异步请求按顺序调用解决方案(真实工作场景,axios

查看控制台打印结果

这样看起来貌似没什么问题,也按顺序输出了。当然,这是理想情况,是因为两个接口都响应的很快,几乎一调用就能返回,所以给我们一种感觉就是按顺序输出了。但是试想一下,如果第一个接口调用的过程中,受到了阻碍,亦或是查询的数据比较耗时,那么结果可能就不一样了。

由于实例中的接口均响应比较快,所以现在在接口一返回的地方增加一个setTimeout,模拟耗时查询(可能不太正确,但是这不是重点)。

let url = https://api.apiopen.top/singlePoetry;

this.$axios.get(url).then((res) => {

setTimeout(()=>{

//模拟耗时操作,需要1s后才返回数据

console.log(res, “res------”);

},1000)

});

let url2 = https://api.apiopen.top/getJoke?page=1&count=2&type=video; this.$axios.get(url2).then((res2) => {

console.log(res2, “res2------”);

});

这个时候控制台打印顺序发生了变化,先输出2,后输出1

虽然接口一写在前面,但是由于其比较耗时,导致先输出接口二的结果,显然这不满足我们最开始的需求。那么如何在不确定接口返回时间的情况下,控制接口输出的顺序呢?这时候就该使用第一种实现方案了–Promise。

在Promise中,使用then()控制执行顺序,当Promise中执行了resolve(),才会继续执行then()里面的,因此这个时候可以把接口一放到Promise里面,接口二放入then()里面,当接口一请求成功之后执行resolve(),才会继续往下调用then()里面的接口二。

new Promise((resolve, reject) => {

let url = https://api.apiopen.top/singlePoetry;

this.$axios.get(url).then((res) => {

setTimeout(() => {

//模拟耗时操作

console.log(res, “耗时返回的res”);

resolve(“success”);

}, 1000);

})

}).then(()=>{ //上一个接口成功resolve之后执行then()

let url2 = https://api.apiopen.top/getJoke?page=1&count=2&type=video;

this.$axios.get(url2).then((res2) => {

console.log(res2, “res2------”);

})

})

控制台按顺序输出,可以实现需求。

那么如果存在两个接口以上,同样需要按顺序,仍然可以使用Promise,但是注意接口二需要返回一个Promise对象。

new Promise((resolve, reject) => {

let url = https://api.apiopen.top/singlePoetry;

this.$axios.get(url).then((res) => {

setTimeout(() => {

//模拟耗时操作

console.log(res, “耗时返回的res”);

resolve(“success”);

}, 1000);

})

}).then(()=>{

return new Promise((resolve,reject)=>{ //注意该处需要返回一个Promise对象

let url2 = https://api.apiopen.top/getJoke?page=1&count=2&type=video;

this.$axios.get(url2).then((res2) => {

console.log(res2, “res2------”);

resolve(“success”);

})

})

}).then(()=>{

//其他接口,此处用setTimeout模拟异步请求

setTimeout(()=>{

console.log(‘res3------’)

},100)

})

控制台打印输出结果,实现按顺序。

如果有3、4、5个甚至更多的呢,同样的写法,除了最后一个(当然最后一个也可以返回),中间的都需要返回一个Promise对象,因为这样才能使用then()方法实现按顺序执行,并且每个接口返回成功之后执行resolve()。

更多细节请参考[JavaScript Promise | 菜鸟教程](()

以上的Promise在调用的接口数量少还可以使用,但是当接口很多,使用其就显得有点繁琐,层层回调,导致回调炼狱。在真实工作场景中一般使用相对简单的方式(也是最容易实现的方式)。

使用axios时每一个异步请求都有一个then()方法,代表请求成功,那么我们可以在调用第一个接口成功时,也就是在每个axios的then()里面再去调用下一个接口。

let url = https://api.apiopen.top/singlePoetry;

this.$axios.get(url).then((res) => {

console.log(res, “真实工作场景!”);

let url2 = 《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 https://api.apiopen.top/getJoke?page=1&count=2&type=video;

this.$axios.get(url2).then((res2) => { //在第一个接口请求完成之后调用下一个,保证顺序

console.log(res2, “res2------”);

//继续调下一个接口…

});

});

控制台打印输出结果

扩展:Generator(了解,一个演变过程)

Generator 顾名思义是生成器,那什么是生成器?官网给出的解释: 使用 function* 语法和一个或多个 yield 表达式以创建一个函数即为生成器,当然它的返回值就是一个迭代器即生成器。生成器可以用来控制执行顺序。Generator的关键是yield跟next()。

详细内容参考[Generator - JavaScript | MDN](()

举个简单的例子

function *gen(){

let y = yield 1 + 1;

let z = yield y + 1;

return z;

}

let step = gen()

console.log(‘generator’,step.next())

控制台打印输出情况

返回的是一个指针对象,done为false表示还没迭代完成。

此时done仍未false,继续完善代码。

function *gen(){

let y = yield 1 + 1;

let z = yield 2 + 1;

return z;

}

let step = gen()

console.log(‘generator’,step.next())

console.log(‘generator’,step.next())

console.log(‘generator’,step.next())

done为ture表示迭代完成,此时value为undefined,继续执行next()结果不变。

实现二:async await

async awiat可以说是promise的改进方案,可以让异步执行的代码看起来同步化,解决了promise的回调炼狱问题,如下对promise的实例进行改造。

promise写法

new Promise((resolve, reject) => {

let url = https://api.apiopen.top/singlePoetry;

this.$axios.get(url).then((res) => {

setTimeout(() => {

  • 13
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值