如何使用异步Node.js最好地处理此分页?

时间:2017-02-25 16:20:45

标签: node.js asynchronous

我的问题涉及使用异步代码。

这是相关的伪代码:

function handleQueryMore(result) {
    conn.queryMore(result.nextRecordsUrl, function(err, resultMore){    
        if (err) {}
        //do stuff with result
        if (!resultMore.done){
            handleQueryMore(resultMore);
        }
    });
}

//(below code runs first when launched of course)

var conn = new jsforce.Connection({////etc
var sql = "SELECT //.......

conn.query(sql, function(err, result) {
    if (err) {}
    //do stuff with result

    if (!result.done) //didn't pull all records
    {
        handleQueryMore(result);
    }               
});

初始查询仅返回特定的最大记录数,然后递归调用handleQueryMore()来处理每个额外的记录块。

最初我在conn.query()循环中有一个(!result.done){}但当然问题是conn.query()代码异步运行并且没有机会在循环的下一次运行(导致〜无限无目的循环)。

有第三方库方法可以使代码同步运行,但我的猜测是有一些我没有遵循的基本设计范例。递归有效,但我担心如果查询返回大量的记录,可能需要的内存量。

即使我知道需要分页的记录数量,我必须有result.nextRecordsUrl分页,在每次执行前一个查询之前我都无法得到...所以我不能只是同时运行它们。

有人关心这个吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

使用async.js包。

function handleQueryMore(result) {

  conn.queryMore(result.nextRecordsUrl, function(err, resultMore) {
    if (err) {}
    //do stuff with result
    else {
      async.each(result.data, function(individualData, callback) {
        // do some async task
        callback(); // to tell that this is completed
        //callback(err); if there is any error while processing data
      }, function(error) {
        if (!error) {
          if (!result.done) //didn't pull all records
          {
            handleQueryMore(result);
          }
        }
      });
    }
  });


}



var conn = new jsforce.Connection({ ////etc
  var sql = "SELECT //.......

  conn.query(sql, function(err, result) {
    if (err) {} else {
      async.each(result.data, function(individualData, callback) {
        // do some async task
        callback(); // to tell that this is completed
        //callback(err); if there is any error while processing data
      }, function(error) {
        if (!error) {
          if (!result.done) //didn't pull all records
          {
            handleQueryMore(result);
          }
        }
      });
    }
  });
});

答案 1 :(得分:1)

我根本就不会这样做。随着您获得更大的数据集,它的效率非常低。相反,我会接受查询字符串参数,指示我想要开始的记录索引和要返回的计数。所有数据库都具有相同的skip和take(例如,如果您使用jsforce方法链API,则可以执行.skip(5).take(10)以返回集合中的记录6-16)。这样可以大大简化您的代码,并通过使每个请求独立于其他请求来降低风险。

另外,我注意到评论//(below code runs first when launched of course),但这也不是一个好主意。理想情况下,您希望按需查询数据库,而不是在应用程序启动时查询。这也可能就是为什么你遇到了你所面临的挑战。

答案 2 :(得分:1)

如果你正在使用mongo db,那么试试这个..

   user.aggregate({ $match: { status: true, type: req.query.type } },
        { "$skip": (skipValue) }, { "$limit": limitValue },
        (err, data) => {
//Code
})