0

I perform an async search call. The search results are not returned in one go. I get max 200 results at once. For next set of results I have to extract bookmark from the first set of results. So the query should happen sequentially. I have written following code but its not working. The next loop (for loop) is executing without finishing the first query. I dont know how to resolve this.

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

I also tried

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

with callback but this is overflowing stack. I am not sure why as in my test case there are only 300 results so it should ideal run only once here.

2
  • var data = getQueryResult(resourcetypeStr, startTime, endTime, bookmark).then () Isn't this overwriting the the outer data variable every time? I have a hunch that your promsies are getting garbage collected every time, since you overwrite each promise with the next one. Try implementing this with Promise.all() and save yourself a headache. :) Commented Feb 9, 2017 at 12:20
  • The problem is that the for loop is proceeding before the search data returns. And next bookmark should be from the data of first search. Commented Feb 9, 2017 at 12:41

1 Answer 1

1

Have you tried something like this?

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;

When the getQueryResult returns, if the length is 0, we're done and can resolve the outer promise, else call getQueryResult again with the same callback until the length is 0. SO instead of a for loop, have each resolving getQueryResult call the next one if needed.

If this is similar to your second try, check the values of data.row.length, since this can only go infinite if data.row.length is never 0.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. Its similar to my second try. There was some other issue with my code so the second approach was not working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.