请问 Vue-Resource 用链式操作进行有先后顺序的 Ajax 请求要怎么写才不会变成回调地狱?

2017-02-07 08:45:00 +08:00
 matts8023

如题。因为业务需求,有个地方需要进行 3 次 Ajax 请求,不用 Vue-Resource 时写的话就有三层回调,代码显得臃肿。后来使用了 Vue-Resource ,以为 Promise 的特性能避免这个问题,没想实际写的时候却陷入同一种思维里。

    Vue.$http.get('/test1').then(function() {
        
        Vue.$http.get('/test2').then(function() {
        
            Vue.$http.get('/test3').then(function(response) {
        
                console.log(response);

            });

        });
       
    });

请问如何优雅的用链式操作写这个 Ajax ?

7933 次点击
所在节点    前端开发
11 条回复
k9982874
2017-02-07 08:56:19 +08:00
不关 vue-resource 的事, promise 基础不扎实。
```javascript
Vue.$http.get('/test1').then(response => {
// 处理第一次返回的 response
return Vue.$http.get('/test2')
}).then(response => {
// 处理第二次返回的 response
return Vue.$http.get('/test3')
}).then(response => {
// 处理第三次返回的 response
console.log(response);
}).catch(err => {
// 处理错误
console.log(err);
})
```
ccccccc
2017-02-07 09:10:26 +08:00
使用 promise.all 另外官方已经推荐 axios
zhuangtongfa
2017-02-07 09:15:34 +08:00
promise.all
zhuangtongfa
2017-02-07 09:24:21 +08:00
const promises = ["/test1", "/test2", "/test3"]
.map(item => {
return Vue.$http.get(item)
})
// 方法一
Promise.all(promises)
.then(res => {
console.log(res)
})

// 方法二:使用 async/await

async function getData() {
const res = await Promise.all(promises)
}
ChefIsAwesome
2017-02-07 09:33:17 +08:00
如果你是第二步依赖第一步的结果,第三步依赖第二步的结果。那写出来肯定是一个套另一个的。 Promise 不是拿来解决这种问题的。
matts8023
2017-02-07 10:02:38 +08:00
@k9982874 谢谢!
matts8023
2017-02-07 10:05:08 +08:00
@zhuangtongfa 谢谢,的确优雅了很多!
matts8023
2017-02-07 10:05:49 +08:00
@ChefIsAwesome promise.all 可以做到这种控制执行先后顺序的效果
ChefIsAwesome
2017-02-07 10:52:22 +08:00
@matts8023 all 是几个东西同时出去,等全部完成后收集结果。没有依赖关系。
zhuangtongfa
2017-02-07 13:35:58 +08:00
@ChefIsAwesome @matts8023
Promise.alll 不保证顺序,如果要顺序,可以使用 bluebird 提供的 Promise.mapSeries,保证顺序
zhuangtongfa
2017-02-07 13:43:12 +08:00
import Promise from 'bluebird'
// 方法一
Promise.mapSeries(["/test1", "/test2", "/test3"], url => Vue.$http.get(url))
.then(function (results) {
console.log(results)
})
// 方法二:使用 async/await
async function getData() {
const results = await Promise.mapSeries(["/test1", "/test2", "/test3"], url => Vue.$http.get(url))
console.log(results)
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/338620

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX