2017-02-09 156 views
0

我執行異步搜索調用。搜索結果不會一次返回。我一次獲得最多200個結果。對於下一組結果,我必須從第一組結果中提取書籤。所以查詢應該順序發生。我寫了下面的代碼,但它不工作。下一個循環(for循環)正在執行而沒有完成第一個查詢。我不知道如何解決這個問題。遞歸調用nodejs中的異步函數

var getQueryResult = function(resourcetypeStr, startTime, endTime, bookmark){ 
var promise = new Promise(function(resolve, reject) { 
    var options = { 
      OPTIONS 
    }; 
    search(DESIGN_DOC, INDEX, options) //Async function 
    .then(function (data) { 
     resolve(data); 
    }) 
    .catch(function(error){ 
     logger.error("Error querying database " + resourcetypeStr + ": " + error); 
     return reject(error); 
    }); 
}); 
    return promise; 
}; 

var getRemainingData = function(resourcetypeStr, startTime, endTime, bookmark, number){ 

    var promise = new Promise(function(resolve, reject){ 
    var result; 
    for(i = 0; i<number; i++){ 
     var data = getQueryResult(resourcetypeStr, startTime, endTime, bookmark).then (function(data){ 
     if(result){ 
      result = result.concat(data); 
     }else{ 
      result = data; 
     } 
     if(data.row.lenth ===0){ 
      resolve(result); 
     } 
     bookmark = data.bookmark; 
     return data; 
    }); 
    } 
    }); 
return promise; 
}; 


var getResources = function (resourcetypeStr, list, startTime, endTime) { 
var promise = new Promise(function(resolve, reject) { 
    var options = { 
      OPTIONS 
    }; 
    return search(DESIGN_DOC, INDEX, options)//Async function 
    .then(function (data){ 
     if(data.total_rows > 200){ 
      debugger; 
      getRemainingData(resourcetypeStr, startTime, endTime, data.bookmark, function(result){ 
       resolve(data.concat(result)); 
      }); 
     }else{ 
      resolve(data); 
     } 
    }) 
    .catch(function(error){ 
     console.log("reject error :"+error); 
     return reject(error); 
    }); 
    }); 
    return promise; 
}; 

我也試過

function getRemainingData(resourcetypeStr, uuidQueryString, startTime, endTime, bookmark, number, callback) { 
    var result; // clone collection 
    (function getOne(resourcetypeStr, uuidQueryString, startTime, endTime, bookmark) { 
     console.log("getOne is called"); 
    getRemainingData(resourcetypeStr, uuidQueryString, startTime, endTime, bookmark).then(function(data){ 
     if(result){ 
      result = result.concat(dataToJson(data)); 
     }else{ 
      result = dataToJson(data); 
     } 
     if(data.row.lenth ===0){ 
      callback(result); 
     }else{ 
      setTimeout(getOne(resourcetypeStr, uuidQueryString, startTime, endTime, data.bookmark), 0); 
     } 
    }); 
    })(); 
} 

有回調,但是這是滿溢的堆棧。我不確定爲什麼在我的測試案例中只有300個結果,所以它應該只在這裏運行一次。

+0

'VAR數據= getQueryResult( resourcetypeStr,startTime,endTime,bookmark).then()'是不是每次都覆蓋外部數據變量?我有一種預感,你的pr are病每次都會收集垃圾,因爲你用下一個承諾覆蓋每個承諾。試着用'Promise.all()'來實現這一點,並保存你自己的頭痛。 :) – Shilly

+0

問題是for循環在搜索數據返回之前正在進行。下一個書籤應該來自首次搜索的數據。 – yogeshkakde

回答

1

你有沒有嘗試過這樣的事情?

var promise = new Promise(function(resolve, reject){ 
    var result, 
     callback = function callback(data) { 
      if (result) { 
       result = result.concat(data); 
      } else { 
       result = data; 
      } 
      if (data.row.length ===0) { 
       resolve(result); 
      } 
      else { 
       getQueryResult(resourcetypeStr, startTime, endTime, bookmark).then(callback); 
      } 
     }; 
    getQueryResult(resourcetypeStr, startTime, endTime, bookmark).then(callback); 
}); 
return promise; 

當getQueryResult回報,如果長度爲0,我們就大功告成了,可以解決外的承諾,否則打電話getQueryResult同樣具有相同的回調,直到長度爲0。因此,而不是一個for循環,如果需要,每個解析getQueryResult都會調用下一個。

如果這類似於你的第二次嘗試,檢查data.row.length的值,因爲這隻能去無限的,如果data.row.length是從來沒有0

+0

謝謝。它類似於我的第二次嘗試。我的代碼還存在其他一些問題,所以第二種方法不起作用。 – yogeshkakde