reactjs setInterval中的fetch API

k5hmc34c  于 2023-08-04  发布在  React
关注(0)|答案(1)|浏览(108)

我正在调用API调用链,最后一个API需要调用多次。下面是我在setInterval抛出错误时调用的函数:

function firstAPI(){
    return fetch(url)
}
function secondAPI(key){
    return fetch(url)
}
async function dataFetch(){
    try{
        let firstAPIData = await firstApi();
        if(!firstAPIData?.ok){
            throw Error(firstAPIData.text())
        }
        let firstAPIResponse = await firstAPIData.json();//response{key:'abc'}
        let i=1,flag=0;
        let interval = setInterval(async function(){
            if(i<10){
                let secondAPIData = await secondAPI(firstAPIResponse.key)
                if(!secondAPIData.ok){
                    clearInterval(interval)
                    throw Error(secondAPIData.text())
                }
                let secondAPIResponse = await secondAPIData.json();//{data:[],status:'COMPLETE'}
                if(secondAPIResponse.status == 'COMPLETE'){
                    flag =1;
                }
                i++;
                if(flag ==1){
                    clearInterval(interval)
                    throw Error('error')
                }
            }
            
        },1000)
        
    }
    catch(error){
        console.log(error)
    }
}
dataFetch()

字符串
它应该给予正确的错误响应

cqoc49vn

cqoc49vn1#

当你在setTimeoutsetInterval中运行时,它们不会像你在这里期望的那样同步执行。相反,它们被安排在稍后运行。因为它们在稍后运行,它们不再在try/catch块中,因此错误是未捕获的。你可以在这里阅读更多关于事件循环的信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#event_loop
在你的例子中,我会创建一个异步的“sleep”函数:

function sleep(ms){
 return new Promise ((resolve, _reject) => {
  setTimeout(resolve, ms)
 })
}

字符串
然后你可以在循环中执行await sleep(1000),而不是超时:

function firstAPI(){
    return fetch(url)
}
function secondAPI(key){
    return fetch(url)
}
async function dataFetch(){
    try{
        let firstAPIData = await firstApi();
        if(!firstAPIData?.ok){
            throw Error(firstAPIData.text())
        }
        let firstAPIResponse = await firstAPIData.json();//response{key:'abc'}
        let flag=0;
        for (let i = 0; i < 10; i++) {
         let secondAPIData = await secondAPI(firstAPIResponse.key)
         if(!secondAPIData.ok){
          throw Error(secondAPIData.text())
         }
         let secondAPIResponse = await secondAPIData.json();//{data:[],status:'COMPLETE'}
         if(secondAPIResponse.status == 'COMPLETE'){
          flag =1;
          throw Error('error')
          // I guess you want to return something here instead of throwing the error?
         }
         // wait 1 second (I guess you have this to not run into rate limits)
         await sleep(1000)
        }
    }
    catch(error){
        console.log(error)
    }
}
dataFetch()


这并不是代码的精确表示,因为它会等待请求,然后再等待1秒,而不是每秒发出一个新请求并忽略上一个请求的结果,如果你真的需要,你可以使用Promise.race()获得一秒超时行为。

相关问题