【问题标题】:Recursive call to a async function in nodejs递归调用nodejs中的异步函数
【发布时间】:2017-06-27 10:46:09
【问题描述】:

我执行异步搜索调用。搜索结果不是一次性返回的。我一次最多可以得到 200 个结果。对于下一组结果,我必须从第一组结果中提取书签。所以查询应该按顺序发生。我已经编写了以下代码,但它不起作用。下一个循环(for 循环)正在执行而没有完成第一个查询。我不知道如何解决这个问题。

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 个结果,所以它应该只在这里运行一次。

【问题讨论】:

  • var data = getQueryResult(resourcetypeStr, startTime, endTime, bookmark).then () 这不是每次都覆盖外部数据变量吗?我有一种预感,你的承诺每次都会被垃圾收集,因为你用下一个承诺覆盖了每个承诺。尝试使用Promise.all() 来实现这一点,让自己头疼。 :)
  • 问题是在搜索数据返回之前for循环正在继续。下一个书签应该来自第一次搜索的数据。

标签: javascript node.js asynchronous recursion


【解决方案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,我们就完成了并且可以解析外部 promise,否则使用相同的回调再次调用 getQueryResult,直到长度为 0。所以而不是 for 循环,每个解析 getQueryResult如果需要,请调用下一个。

如果这与您的第二次尝试类似,请检查 data.row.length 的值,因为只有在 data.row.length 永远不会为 0 时,这才能无限。

【讨论】:

  • 谢谢。它类似于我的第二次尝试。我的代码还有其他问题,所以第二种方法不起作用。
猜你喜欢
  • 2016-09-21
  • 2017-06-08
  • 2014-05-21
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
  • 2017-03-12
  • 2020-09-08
  • 2013-12-07
相关资源
最近更新 更多