无法通过递归调用node.js中的函数从promises获得响应
Posted
技术标签:
【中文标题】无法通过递归调用node.js中的函数从promises获得响应【英文标题】:Unable to get response from promiese with recursively calling the function in node.js 【发布时间】:2018-05-04 12:16:11 【问题描述】:使用 node.js Q 承诺库我怀疑递归调用函数是否有用。我尝试了两种方法来解决我的问题。在第一种方法中,我尝试直接从递归函数返回,而在第二种方法中,我尝试使用 Q Promise 库。
这是我调用递归函数并期待响应的代码。
function getSearchedUserInTree(userId,body)
var deferred = Q.defer();
var loggedInUserId = userId;
var searchUserIdSql = "SELECT rc.user_id,CAST(b.node_id AS CHAR) AS node_id FROM refer_codes AS rc LEFT JOIN btrees AS b ON b.user_id=rc.user_id WHERE rc.refer_code='"+body.refer_code+"'";
connection.query(searchUserIdSql, function (err, result,field)
var getLoggedInNode = "SELECT CAST(b.node_id AS CHAR) AS node_id FROM btrees as b WHERE b.user_id='"+loggedInUserId+"'";
connection.query(getLoggedInNode, function (err, loggedResult,field)
helper.trackRelation(loggedResult[0].node_id,result[0].node_id,function(err,relationResult)
if(err) throw err;
deferred.resolve(relationResult);
);
);
);
return deferred.promise;
第一种从带有承诺的“trackRelation()”函数中获取回报的方法。
function trackRelation(parentNode,childNode)
var deferred = Q.defer();
var childNodeId = bigInt(""+childNode+"");
var parentNodeId = bigInt(""+parentNode+"");
if(bigInt(childNodeId).compare(parentNodeId) == 0)
var childSql = "SELECT * FROM users WHERE id='"+childNodeId.toString()+"'";
connection.query(childSql,function(err,packResult,field)
console.log(packResult);
deferred.resolve(status:200,message:'success',packResult);
);
else
/* Detact position */
if(bigInt(childNodeId).mod(2) == 0)
var tempParentNodeId = bigInt(childNodeId).divide(2);
else
var subResult = bigInt(childNodeId).subtract(1);
var tempParentNodeId = subResult.divide(2);
/** If reached at top but parent not found **/
if(bigInt(tempParentNodeId).compare(1) == 0)
var childSql = "SELECT * FROM users WHERE id='"+tempParentNodeId.toString()+"'";
connection.query(childSql,function(err,packResult,field)
console.log(packResult);
deferred.resolve(status:200,message:'success',packResult);
);
else
return trackRelation(parentNodeId,tempParentNodeId.toString());
return deferred.promise;
从递归函数中获取返回值的第二种方法,直接返回值,没有承诺。
function trackRelation(parentNode,childNode)
var deferred = Q.defer();
var childNodeId = bigInt(""+childNode+"");
var parentNodeId = bigInt(""+parentNode+"");
if(bigInt(childNodeId).compare(parentNodeId) == 0)
deferred.resolve(status:200,message:'success',topUserId:childNodeId.toString());
return childNodeId.toString();
else
/* Detact position */
if(bigInt(childNodeId).mod(2) == 0)
var tempParentNodeId = bigInt(childNodeId).divide(2);
else
var subResult = bigInt(childNodeId).subtract(1);
var tempParentNodeId = subResult.divide(2);
/** If reached at top but parent not found **/
if(bigInt(tempParentNodeId).compare(1) == 0)
return tempParentNodeId.toString();
else
return trackRelation(parentNodeId,tempParentNodeId.toString());
return deferred.promise;
我没有从这两种方法中得到任何回应。我试图在控制台中打印我需要响应的值,我得到的值与期望的值相同,但无法得到响应的值。
【问题讨论】:
在else
的情况下,您永远不会调用deferred.resolve
在我的第一种方法中,我已经使用了 deferred.resolve(status:200,message:'success',packResult); .是不是正确的使用方式?
【参考方案1】:
你不能像从回调中返回的方式从 Promise 中返回值。
您的方法 trackRelation
返回一个应使用 .then()
方法访问其值的承诺。
例子:
trackRelation(args).then(function(res)
//when the promise resolves, this method is called
, function(err)
//when the promise rejects, this method is called
);
查看 API 参考页面here。
【讨论】:
感谢 Parijat 的回答,这实际上对我有用。你能解释一下我做错了什么以及如何解决node.js中的此类问题吗?还有一件事,你能告诉我在得到想要的结果后如何停止递归吗? 正如您所说的那样,它对您有用,我将简要解释一下..您为返回承诺的函数做了trackRelation(args,callback)
。相反,如果您使用trackRelation(args).then(passCallback, failCallback)
,它应该可以正常工作。就递归而言,如果您希望使用递归 Promise,请先让递归 Promise 解决,然后再解决当前的 Promise。我的意思是做类似的事情:elsetrackRelation(parentNodeId,tempParentNodeId.toString(),function(res)defer.resolve(res);)
以上是关于无法通过递归调用node.js中的函数从promises获得响应的主要内容,如果未能解决你的问题,请参考以下文章