2017-04-18 932 views
1

我正在使用axios向Deezer API發出請求。不幸的是,在Deezer的API中,當您請求藝術家的專輯時,它不包含專輯曲目。所以,我正在通過請求藝術家的專輯,然後對每個專輯執行後續的axios請求來解決這個問題。我遇到的問題是API將請求限制爲每5秒50次。如果藝術家擁有超過50張專輯,我通常會收到「超出配額」的錯誤。有沒有辦法將axios請求限制爲每5秒50次,特別是在使用axios.all時?所有的節流Axios請求

var axios = require('axios'); 

function getAlbums(artistID) { 
    axios.get(`https://api.deezer.com/artist/${artistID}/albums`) 
    .then((albums) => { 
     const urls = albums.data.data.map((album) => { 
     return axios.get(`https://api.deezer.com/album/${album.id}`) 
      .then(albumInfo => albumInfo.data); 
     }); 
     axios.all(urls) 
     .then((allAlbums) => { 
      console.log(allAlbums); 
     }); 
    }).catch((err) => { 
     console.log(err); 
    }); 
} 

getAlbums(413); 

回答

1

首先,讓我們看看你真正需要。如果您有大量相冊,您的目標是每100毫秒請求一次。 (使用axios.all這個問題與使用Promise.all沒什麼不同,你只是想等待所有的請求完成。)

現在,與axios你有攔截API,允許在請求之前插入你的邏輯。所以,你可以使用這樣的攔截器:

function scheduleRequests(axiosInstance, intervalMs) { 
    let lastInvocationTime = undefined; 

    const scheduler = (config) => { 
     const now = Date.now(); 
     if (lastInvocationTime) { 
      lastInvocationTime += intervalMs; 
      const waitPeriodForThisRequest = lastInvocationTime - now; 
      if (waitPeriodForThisRequest > 0) { 
       return new Promise((resolve) => { 
        setTimeout(
         () => resolve(config), 
         waitPeriodForThisRequest); 
       }); 
      } 
     } 

     lastInvocationTime = now; 
     return config; 
    } 

    axiosInstance.interceptors.request.use(scheduler); 
} 

它的作用,使他們在intervalMs毫秒間隔執行是時間的請求。

在您的代碼:

function getAlbums(artistID) { 
    const deezerService = axios.create({ baseURL: 'https://api.deezer.com' }); 
    scheduleRequests(deezerService, 100); 

    deezerService.get(`/artist/${artistID}/albums`) 
     .then((albums) => { 
      const urlRequests = albums.data.data.map(
        (album) => deezerService 
         .get(`/album/${album.id}`) 
         .then(albumInfo => albumInfo.data)); 

      //you need to 'return' here, otherwise any error in album 
      // requests will not propagate to the final 'catch': 
      return axios.all(urls).then(console.log); 
     }) 
     .catch(console.log); 
} 

這,然而,一個簡單的方法,你的情況,你可能想以最快的速度收到了效果,儘可能爲請求的數量少於50對於這一點,你必須在調度器內部添加某種計數器,它將根據間隔和計數器來計算請求的數量並延遲它們的執行。