2017-07-04 43 views
4

請記住,我是node.js的新手,我使用的是android開發。使用node.js並承諾獲取分頁數據

我的情況是這樣的:

  1. 運行對返回null或值
  2. 呼叫與數據庫值的web服務的數據庫,它提供信息分頁查詢,這意味着在調用如果有更多的信息要獲取,我會得到一個參數傳遞給下一個調用。
  3. 的所有項目進行檢索後,將它們存儲在數據庫中的表
  4. 如果一切順利,先前收到的每一個項目,我需要讓其他Web呼叫,存儲檢索信息在另一個表
  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) 
     } 

    }) 

有幾件事情失蹤,從我TES ted,getAllData.then僅針對第一組項目觸發一個,而不針對其他項目,因此清楚地處理返回的數據不正確。

後編輯:我已編輯場景。鑑於一些更多的研究,我的感覺是我可以使用鏈或.then()來按順序執行操作。

+1

這裏:https://stackoverflow.com/questions/44783797/nodejs-inserting-data-into-postgresql-error你可以找到一個實例與pg-promise異步拉數據的例子。 –

+0

謝謝@重要 - 但由於我是節點新手,所以很難理解。我已經使用knex for postgres插入並且工作正常。在理解它之前,我需要更詳細地研究其他問題的答案 – Alin

+1

您可能在事務之外使用了knex。這一次更棘手。您需要一個事務,以便能夠回滾更改,並且需要運行無限的異步序列。這就是那個例子的作用。 –

回答

1

是的,它正在解決第一次通話本身的承諾時發生。您應該將解析(值)放入if語句中,以檢查是否需要獲取更多數據。當節點異步時,您還需要重構邏輯。除非你改變邏輯,否則上述代碼將不起作用。

解決方案1:

您可以添加您正在呼叫的上下文之外的另一個變量的分頁響應。稍後在完成響應後使用該值。

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

我還沒有測試過,但像這樣的東西應該工作。如果問題仍然存在,請在評論中告知我。

解決方案2:

您可以刪除的承諾,並嘗試與回調同樣的事情,因爲它們更容易執行,將是有意義的誰是熟悉的結構語言的程序員。

+0

謝謝你花時間迴應我。正如標題所述,在你的回答中,我沒有看到在任何地方使用的承諾,並且這是一個使用它的請求。 – Alin

+1

@Alin我在回答問題後更改了標籤。更新了答案。它應該工作我猜。 – vijaykrishnavanshi

+0

我編輯了場景。如果是這種情況,你能否更新你的答案?感謝您的時間。 – Alin

0

看看你的問題,我創建了一個代碼,可以循環承諾。 並且只有在有更多數據要被提取時纔會繼續,所存儲的數據仍然可以在數組中使用。 我希望這個幫助。不要忘記標記是否有幫助。

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

如果你想這樣做,更多的時候我也參考創建gist。 如果你不想使用任何全局變量,並想以非常實用的方式來完成。你可以檢查這個example。但它需要更多的複雜性。