推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
abcbuzhiming

如何用 js 优雅的在前端实现循环多次向后端的 ajax 请求,且这些 ajax 是按顺序发起的

  •  
  •   abcbuzhiming · Apr 6, 2017 · 12235 views
    This topic created in 3348 days ago, the information mentioned may be changed or developed.
    我现在有个这样的需求,前端页面要循环向服务器发起请求,一个请求结束后再发起下一次,直到循环条件结束。为的是缩短服务器每次处理数据时间,并及时的让客户端逐步看到处理结果,以前用 jquery 做,无非就两个方案: 1.aysnc 改成 false 变成同步请求, 2.递归调用,非常丑陋。现在弃用了 jquery ,用的 axios,这个库没法进行同步请求。那该怎么办,只有递归一条路了吗?
    24 replies    2017-04-07 16:49:11 +08:00
    ChefIsAwesome
        1
    ChefIsAwesome  
       Apr 6, 2017 via Android
    只能递归啊。丑不丑还不是看你写法
    murmur
        2
    murmur  
       Apr 6, 2017
    axios 本身基于 promise 你怎么让他同步 加了 async 写的好看但是还是要 babel
    所以最简单的办法还是一开始就用 promise
    kindjeff
        3
    kindjeff  
       Apr 6, 2017   ❤️ 2
    这不叫递归啊~
    murmur
        4
    murmur  
       Apr 6, 2017
    对了,如果你会用英文搜索的话,你会发现有一种优雅的写法可以像 Promise.all 一样让一个数组的 promise 按顺序执行,而且不用自己串链子

    问题是好像这个方法用的是 reduce 方法,一样需要 polyfill
    binux
        5
    binux  
       Apr 6, 2017
    Promise
    coderfox
        6
    coderfox  
       Apr 6, 2017 via Android
    let req = axois.request(...).then(业务逻辑).then( () => req );
    req();

    思路大概如此,或许有点小问题,自己试试。
    billlee
        7
    billlee  
       Apr 6, 2017
    alexsunxl
        8
    alexsunxl  
       Apr 6, 2017
    上 babel , async await
    viko16
        9
    viko16  
       Apr 6, 2017 via Android
    websocket 会不会是更好的方案?
    golmic
        10
    golmic  
       Apr 6, 2017 via Android
    对啊,我也觉得上 socket
    Biwood
        11
    Biwood  
       Apr 6, 2017
    写聊天程序?长轮询?这个很常见吧,异步回调而已,不算递归,没有那么高大上
    vghdjgh
        12
    vghdjgh  
       Apr 6, 2017
    1 、就用递归的写法(纯函数式语言的标准写法啊,不丑的)
    即:每次只处理第一个 promise ,处理后把数组的其它部分作为新数组递归执行,直到全部完成
    2 、 async/await
    类似于:
    ```
    async function main(promises) { // promises 是一个 promise 数组
    let result = 0;
    for(let promise of promises) {
    result += await promise;
    }
    return result;
    }
    ```
    3 、和后端商量下用 websocket 推数据给你(现在轮询的方式很落后了吧)。
    abcbuzhiming
        13
    abcbuzhiming  
    OP
       Apr 6, 2017
    @viko16 条件不允许上 websocket
    abcbuzhiming
        14
    abcbuzhiming  
    OP
       Apr 6, 2017
    @vghdjgh
    @coderfox
    谢谢,正在研究改造成 promise ,环境暂时不允许用 async
    shyling
        15
    shyling  
       Apr 6, 2017
    Rx.Observable.from(...)
    .flatMap(source => fetch(source), 1)
    .subscrible()
    lujiajing1126
        16
    lujiajing1126  
       Apr 6, 2017
    支持#15

    把 Promise 转成 Observable ,然后用 rxjs/repeatproto 来重复执行

    https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/repeatproto.md
    otakustay
        17
    otakustay  
       Apr 6, 2017
    转 rx 是个办法但侵入性太强,其实你用 promise 或 callback 的话直接找个 async 库做下 series 封装就行了
    http://caolan.github.io/async/
    lkytal
        18
    lkytal  
       Apr 6, 2017
    async 库就解决了...
    zbinlin
        19
    zbinlin  
       Apr 6, 2017 via Android
    自荐一个类似的 async 库: https://www.npmjs.com/package/serial-async

    :)
    libook
        20
    libook  
       Apr 7, 2017
    这是一个流程控制库 https://caolan.github.io/async/index.html
    zhouyg
        21
    zhouyg  
       Apr 7, 2017   ❤️ 1
    不用库就可以有优雅的写法:
    [promiseFn1, promiseFn2,promiseFn3].reduce((promise, fn)=>{
    return promise.then(fn);
    },promiseFn0() );
    coldsnap
        22
    coldsnap  
       Apr 7, 2017
    ```
    function each (promises, cb) {
    return promises.reduce((promise, task, i) => {
    return promise.then(_ => task).then(_ => cb(_, i))
    }, Promise.resolve())
    }
    ```

    用法和 bluebird 的 each 一样。
    ref: http://bluebirdjs.com/docs/api/promise.each.html
    dangyuluo
        23
    dangyuluo  
       Apr 7, 2017
    感觉 websocket 才是正解。
    ryanzyy
        24
    ryanzyy  
       Apr 7, 2017
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2678 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 69ms · UTC 10:31 · PVG 18:31 · LAX 03:31 · JFK 06:31
    ♥ Do have faith in what you're doing.