递归异步api调用

时间:2017-05-27 06:30:38

标签: javascript node.js asynchronous recursion

我正在开发一个需要我使用twitter api的项目。试图返回给定用户的所有关注者。问题是让所有用户bc twitter将单独的粉丝分成最多200个块。

我在网上看到了一个解决方案,他们递归地调用了回调函数,但是我在试图使用promises来获取所有数据之前就陷入了困境。目前它等待第一页回来但是如何让它等待所有的承诺返回。 有人可以给我任何提示/提示,如果有办法迭代地这样做吗?

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
})

2 个答案:

答案 0 :(得分:2)

你很接近,但你的方法只需要一些调整:

  • 如果出现错误,请勿执行除reject()
  • 以外的任何操作
  • 不要创建新的嵌套承诺,而是使用当前的承诺:延迟resolve()(或reject())的任何调用,直到调用下一个回调为止。
  • 光标达到0时仅resolve()
  • 最终的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 :(得分: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()处理程序返回新的promise以自动将其链接到先前的promise。

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()处理程序中执行此操作,这样就可以累积所需的总数据(不显示任何内容)关于你想要收集什么类型的结果,所以这段代码没有显示出来。)