使用node.js并承诺获取分页数据

请记住,我是node.js的新手,我使用的是android开发。

我的情况是这样的:

  1. 针对返回null或值的数据库运行查询
  2. 使用该数据库值调用Web服务,该数据库提供分页信息,这意味着在调用中,如果有更多信息要获取,我将获得一个参数以传递给下一个调用。
  3. 所有的项目被检索后,将它们存储在数据库表中
  4. 如果一切正常,对于以前收到的每件商品,我需要再次进行networking通话,并将检索到的信息存储在另一个表中
  5. 如果提取任何数据集失败,则必须从数据库中恢复所有数据

到目前为止,我已经试过这个:

getAllData: function(){ self.getMainWebData(null) .then(function(result){ //get secondary data for each result row and insert it into database } } getMainWebData: function(nextPage){ return new Promise(function(resolve, reject) { module.getWebData(nextPage, function(errorReturned, response, values) { if (errorReturned) { reject(errorReturned); } nextPage = response.nextPageValue; resolve(values); }) }).then(function(result) { //here I need to insert the returned values in database //there's a new page, so fetch the next set of data if (nextPage) { //call again getMainWebData? self.getMainWebData(nextPage) } }) 

有一些东西遗漏了,从我testing的getAllData.then只触发第一组项目而不是其他人,所以清楚地处理返回的数据不正确。

后来编辑:我编辑了这个场景。 给我更多的研究,我的感觉是,我可以使用一个链或.then()来按顺序执行操作。

是的,它正在解决第一次通话本身的承诺。 你应该把parsing(价值)内的if语句,检查是否需要更多的数据被提取。 当节点asynchronous时,您还需要重构逻辑。 上面的代码将不会工作,除非你改变逻辑。

解决scheme1:

您可以将分页的响应附加到您正在进行的调用的上下文之外的另一个variables。 稍后在完成响应后使用该值。

 getAllData: function(){ self.getMainWebData(null) .then(function(result){ // make your database transaction if result is not an error } } function getList(nextpage, result, callback){ module.getWebData(nextPage, function(errorReturned, response, values) { if(errorReturned) callback(errorReturned); result.push(values); nextPage = response.nextPageValue; if(nextPage) getList(nextPage, result, callback); else callback(null, result); }) } getMainWebData: function(nextPage){ return new Promise(function(resolve, reject) { var result = []; getList(nextpage, result, function(err, results){ if(err) reject(err); else{ // Here all the items are retrieved, you can store them in a database table // for each item received make your web call and store it into another variable or result set // suggestion is to make the database transaction only after you have retrieved all your data // other wise it will include database rollback which will depend on the database which you are using // after all this is done resolve the promise with the returning value resolve(results); } }); }) } 

我没有testing过,但这样的事情应该工作。 如果问题仍然存在,请在评论中告诉我。

解决scheme2:

您可以删除承诺,并使用callback来尝试相同的事情,因为它们更容易遵循,对于熟悉结构化语言的程序员来说是有意义的。

看看你的问题,我已经创build了一个可以循环承诺的代码。 只有当有更多的数据被提取时才会继续,所存储的数据仍然可以在数组中使用。 我希望这个帮助。 不要忘记标记是否有帮助。

 let fetchData = (offset = 0, limit= 10) => { let addresses = [...Array(100).keys()]; return Promise.resolve(addresses.slice(offset, offset + limit)) } // o => offset & l => limit let o = 0, l = 10; let results = []; let process = p => { if (!p) return p; return p.then(data => { // Process with data here; console.log(data); // increment the pagination o += l; results = results.concat(data); // while there is data equal to limit set then fetch next page // otherwise return the collected result return (data.length == l)? process(fetchAddress(o, l)).then(data => data) : results; }) } process(fetchAddress(o, l)) .then(data => { // All the fetched data will be here }).catch(err => { // Handle Error here. // All the retrieved data from database will be available in "results" array }); 

如果你想多做一些,我也创造了一个参考依据 。 如果你不想使用任何全局variables,并想以非常实用的方式来做到这一点。 你可以检查这个例子 。 但是它需要更多的复杂性。