2017-05-27 128 views
1

我正在開發一個需要我使用twitter api的項目。試圖返回給定用戶的所有追隨者。問題是讓所有的用戶bc twitter分開的追隨者成爲最多200個塊。遞歸異步API調用

我看到一個在線解決方案,在繼續之前。目前它等待第一頁返回,但是idk如何使它等待所有的承諾返回。 有人可以給我任何提示/技巧,如果這是一種迭代方式做到這一點?

let cursor = -1; 
let promise = new Promise((resolve,reject)=>{ 
     twitter.followers({cursor},function callback(data, error){ 
     if(error) 
      reject(false) 
     cursor = data.next_cursor; 
     if(cursor!=0){ 
      new Promise((resolve,reject)=>{ 
       twitter.followers({cursor},callback) 
      }) 
      resolve(true); 
     } 
}) 
}) 
promise.then({ 
    //do stuff 
}) 

回答

1

你接近,但你的方法只是需要一些調整:

  • 當出現錯誤時,不要做任何事情比reject()
  • 不要創建一個新的,嵌套的承諾,但使用當前版本:延遲resolve()(或reject())的任何呼叫,直到下一個回調被調用。
  • 只有resolve()當光標已達到0.
  • 最後的then需要一個回調參數,而不是對象文字。

這裏是調整後的代碼(用虛擬實現的twitter.followers,使其工作):

// Mock implementation, for the snippet to work: 
 
var twitter = { 
 
    followers: function (obj, callback) { 
 
     setTimeout(function() { 
 
      callback({ 
 
       next_cursor: (obj.cursor + 5) % 6 
 
      }, 0); 
 
     }, 100); 
 
    } 
 
} 
 

 
let cursor = -1; 
 
let promise = new Promise((resolve,reject)=>{ 
 
    twitter.followers({cursor}, function callback(data, error){ 
 
     if (error) { 
 
      reject(false) 
 
      return; // Don't continue after error 
 
     } 
 
     cursor = data.next_cursor; 
 
     console.log(cursor); 
 
     if (cursor != 0){ 
 
      // Don't create a new promise, just delay to resolve 
 
      twitter.followers({cursor}, callback) 
 
      return; // don't resolve now 
 
     } 
 
     resolve(true); 
 
    }) 
 
}) 
 
promise.then(function() { // You need a callback function here 
 
    console.log('all done'); 
 
})

1

首先,取得一些數據並返回一個promise的函數。我不知道你究竟會像什麼,但也許是這樣的:

function getFollowers(args) { 
    return new Promise((resolve, reject) => { 
     twitter.followers(args, function(data, error) { 
      if (error) { 
       reject(error); 
      } else { 
       resolve(data); 
      } 
     }); 
    }); 
} 

然後,您可以從.then()處理程序中遞歸調用該函數,從.then()處理程序自動鏈返回新承諾它達到了以前的承諾。

function getAllFollowers(user) { 
    return getFollowers(...).then(data => { 
     if (data.next_cursor) { 
      return getFollowers(...).then(data => { 
       // collect data here 
      }); 
     } else { 
      return accumulated_data; 
     } 
    }); 
} 

getAllFollowers(...).then(data => { 
    // got all data here 
}).catch(err => { 
    // error here 
}); 

注意,這部分是僞代碼,因爲我不跟你在嘗試實現精確的邏輯,或者你正在使用的API。但是,總的想法是,您可以遞歸地從.then()處理程序中返回新的承諾,並且會自動鏈接到之前的承諾。

如果要從所有調用中累積一些數據,則還需要在遞歸調用中的.then()處理函數中執行此操作,以便累積所需的總數據(不會顯示任何類型的內容你試圖收集的結果,所以這段代碼沒有顯示)。

+0

你真棒! 這正是我尋找的邏輯,但由於某種原因,我無法自己想出它。 – Leon

+0

其實我還是有點困惑。 遞歸步驟如何工作? 從僞代碼看來,似乎只有兩個getFollower調用正在進行。 – Leon

+0

等待,我想你的意思是把getAllFollowers,而不是getFollowers,我是對嗎? – Leon