V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
matts8023
V2EX  ›  前端开发

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

  •  
  •   matts8023 · 2017-02-07 08:45:00 +08:00 · 7900 次点击
    这是一个创建于 2646 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题。因为业务需求,有个地方需要进行 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 ?

    11 条回复    2017-02-07 13:43:12 +08:00
    k9982874
        1
    k9982874  
       2017-02-07 08:56:19 +08:00   ❤️ 2
    不关 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
        2
    ccccccc  
       2017-02-07 09:10:26 +08:00 via iPhone
    使用 promise.all 另外官方已经推荐 axios
    zhuangtongfa
        3
    zhuangtongfa  
       2017-02-07 09:15:34 +08:00
    promise.all
    zhuangtongfa
        4
    zhuangtongfa  
       2017-02-07 09:24:21 +08:00   ❤️ 1
    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
        5
    ChefIsAwesome  
       2017-02-07 09:33:17 +08:00
    如果你是第二步依赖第一步的结果,第三步依赖第二步的结果。那写出来肯定是一个套另一个的。 Promise 不是拿来解决这种问题的。
    matts8023
        6
    matts8023  
    OP
       2017-02-07 10:02:38 +08:00
    @k9982874 谢谢!
    matts8023
        7
    matts8023  
    OP
       2017-02-07 10:05:08 +08:00
    @zhuangtongfa 谢谢,的确优雅了很多!
    matts8023
        8
    matts8023  
    OP
       2017-02-07 10:05:49 +08:00
    @ChefIsAwesome promise.all 可以做到这种控制执行先后顺序的效果
    ChefIsAwesome
        9
    ChefIsAwesome  
       2017-02-07 10:52:22 +08:00
    @matts8023 all 是几个东西同时出去,等全部完成后收集结果。没有依赖关系。
    zhuangtongfa
        10
    zhuangtongfa  
       2017-02-07 13:35:58 +08:00
    @ChefIsAwesome @matts8023
    Promise.alll 不保证顺序,如果要顺序,可以使用 bluebird 提供的 Promise.mapSeries,保证顺序
    zhuangtongfa
        11
    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)
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3255 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 13:12 · PVG 21:12 · LAX 06:12 · JFK 09:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.