2017-02-09 16 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データになることはありません場合はこれが唯一の無限行くことができますので、

は、は、data.row.lengthの値をチェックresourcetypeStr、startTime、endTime、bookmark).then() 'これは外部データ変数を毎回上書きしないのですか?私はあなたのプロミスが毎回ガベージコレクションをしていることに感謝しています。あなたが次のものでそれぞれの約束を上書きするからです。 'Promise.all()'でこれを実装してみて、頭痛の種にならないようにしてください。 :) – Shilly

+0

問題は、検索データが返される前にforループが進行していることです。次のブックマークは、最初の検索のデータからのものでなければなりません。 – yogeshkakde

答えて

1

あなたはこれを試しましたか?長さが0の場合getQueryResult戻ると、私たちが行っていると外側の約束を解決することができます

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; 

、他の長さが0 SOの代わりに、ループのためになるまで、同じコールバックで再びgetQueryResultを呼び出し、必要に応じてそれぞれを解決してgetQueryResultが次のgetQueryResultを呼び出すようにしてください。これはあなたの2回目の試行と類似している場合data.row.lengthは= getQueryResult(0

+0

ありがとうございます。私の2回目の試みと似ています。 2番目のアプローチが機能していないので、私のコードでいくつかの他の問題がありました。 – yogeshkakde

関連する問題