2017-02-09 159 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