如何循环进行异步获取?循环变量无法确定?

发布于 2022-09-11 17:51:43 字数 1342 浏览 19 评论 0

需求:利用Github V3版本的API,获取某个用户star的项目个数。

用户的api并没有单独提供star个数,而是提供了这样的接口
"starred_url": "https://api.github.com/users/tj/starred{/owner}{/repo}"

查了一下,,github api采用分页技术,如果用上述默认接口,最多只能返回30条内容。因而需要利用参数获取:https://api.github.com/users/tj/starred?page=1&per_page=100,per_page最大可为100.

也就是说我需要这样GET多个接口,直到获取的接口返回[ ]:
axios.get(`/users/${app.userName}/starred?page=${i++}&per_page=100`)

循环程序是同步执行的,GET请求是异步获取。然而我的循环变量与异步获取的数据有关!那么循环代码要怎么写呢?
下面是我用递归写的代码,不过处理得很慢。。这是demo,可以输入tj试一下,很慢的。

let starredLists = []
                    
!function getStarred(index){
    axios.get(`/users/${app.userName}/starred?page=${index++}&per_page=100`)
        .then(function(response){
            starredLists.push(...response.data)
            console.log(starredLists.length + '   ' + index)
            if(response.data.length == 100)
                getStarred(index);
            if(response.data.length != 100)
                app.stars = starredLists.length;
        })
}(1)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

枕花眠 2022-09-18 17:51:49

一定要循环么 用递归请求呗

囚我心虐我身 2022-09-18 17:51:49

你可以用Promise.all

//get user's starred repos   
//get user's starred repos   
let starredLists = [],
    rq = [];
    
axios.defaults.baseURL = 'https://api.github.com';

for(let i = 1;i < 10; i++){
    rq.push(axios.get(`/users/tj/starred?page=${i}&per_page=100`)
        .then(function (response) {
            if(response.data.length == 0)
                break;
            starredLists.push(...response.data)
            console.log('starredLists.length: '+ starredLists.length)
        }));
}

Promise.all(rq).then(() => {
    // 理想状态下,请求全部成功!
    app.stars = starredLists.length 
}).finally(() => {
    // 这个属性 不管 then 还是 catch 必定进入
    // 可能请求失败了!
    if(!app.stars) {
        app.stars = starredLists.length 
    }   
}); 
飘过的浮云 2022-09-18 17:51:49

用了递归的方式,解决了循环变量无法确定的问题;
同时为了性能,用Promise.all()做了批量请求。获取3个组10个接口(以tj大神的star为例)需要大约10s

//get user's starred repos   
let starredLists = [];
let promiseTen = [], 
    promiseOne;

!function getStarred(index) {
    //用for循环,一次性请求十个接口,加快速度,避免同步-异步-同步的反复切换
    for (let i = 0; i < 10; i++) {
        promiseOne = axios.get(`/users/${app.userName}/starred?page=${index++}&per_page=100`)
            .then(function (response) {
                starredLists.push(...response.data)
            })
        promiseTen.push(promiseOne)
    }
    Promise.all(promiseTen).then(() => {
        if(starredLists.length % 100 == 0)      //检查是否需要递归
            getStarred(index)                       
        else 
            app.stars = starredLists.length        
    })
}(1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文