ajax请求一个异步代码的问题

问题

现在有一个需求,我需要发送n个请求,接口如下
favorite/goods?update_time={time}&page={page}&size={size}
GET到的数据格式为{update_time: Number, data: []}
每个请求是依赖上一个请求的,比如这个请求的update_time要放在下一个请求中,每个请求的page也会++,

需求

我需要一次性拿到n组数据,一次性展示到页面上

限制

公司目前只支持到promise,还不能用yeild和async

提问

请问大家应该怎么做,因为n的个数不一定,我不能手动一直.then去写

阅读 2.7k
3 个回答

没人答自己写了一个。。。代码如下


    //  下拉刷新请求
    request(callback) {
        //  区分首次加载和之后加载,首屏加载会有加载组件,回退定位等
        if (this.isFirstLoaded) {
            //  从localStorage中获取上次加载页数
            let initPage = localStorage.getItem(LS_KEY.goodsPage)
                ? parseInt(localStorage.getItem(LS_KEY.goodsPage), 10)
                : 1;
            localStorage.removeItem(LS_KEY.goodsPage);
            //  扩大初始加载个数
            this.baseNum = initPage * LOAD_SIZE;
            Spinner.show();
            this.initRequest([], initPage, callback);
        }
        else {
            this.loadGoodsData(callback);
        }
        return;
    }

    //  加载首屏数据,用于回退定位
    loadInitData() {
        this.goodsPage++;
        this.goodsInfo.goodsModel.params = {
            favorite_update_time: this.goodsInfo.updateTime,
            page: this.goodsPage,
            size: LOAD_SIZE
        };
        return this.goodsInfo.goodsModel.get();
    }

    //  一个递归请求,可加载多页数据,用于带回退定位的首次加载数据
    initRequest(target = [], stopPage = 1, callback) {
        this.loadInitData()
            .then(data => {
                target = target.concat(data.goodsList);
                this.handleResponse(data);
                if (stopPage === 0) {
                    callback && callback(target);
                    this.isFirstLoaded = false;
                    Spinner.hide();
                    return;
                }
                stopPage--;
                this.initRequest(target, stopPage, callback);
            });
    }

    //  对每次的数据请求进行处理
    handleResponse(data) {
        let goods = this.itemsStore;
        let newLoadList = data.goodsList;
        if (newLoadList.length === 0) {
            this.isFirstLoaded && this.props.showNoGoods();
            this.goodsPage--;
        }
        this.goodsInfo.updateTime = data.updateTime;
        this.updateLocalStorage({
            goodsList: goods.concat(newLoadList),
            updateTime: data.updateTime
        });
    }

如果请求简单,没有callback hell,是不需要用到Promise的....
其实只要简单的递归调用就行了,大概写了个,供你参考
代码没测试过,随手写的,写的不好,轻喷....

let showData = {
    page: 0,
    datas = []
};
function getData(url, nextCallback, finishCallback) {
    let req = new XMLHttpRequest();
    req.responseType = "json";
    req.open("GET", url, true);
    req.onload = ret => {
        if (ret.finished) {
            finishCallback(true, showData.datas);
        } else {
            showData.datas.push(ret);
            nextCallback(ret.time, showData.page, ret.size);
        }
    }
    req.onerror = err => finishCallback(false, showData.datas, err);
}

function queryNext(time, page, size) {
    let req_url = `favorite/goods?update_time=${time}&page=${page++}&size=${size}`;
    getData(req_url, queryNext, finish);
}

function finish(result, datas, err) {
    if (result) {
        // data ready.
    } else {
        // something wrong,
        // display error.
        (err) && alert(err); 
    }
}

queryNext(0,showData.page,0);

当然如果你一定要递归调用Promise可以参考https://segmentfault.com/q/10...

可以使用递归函数

推荐问题
宣传栏