NodeJS 异步回调未完成和渲染把手模板
Posted
技术标签:
【中文标题】NodeJS 异步回调未完成和渲染把手模板【英文标题】:NodeJS Async Callback is Not Finishing & Rendering Handlebars Template 【发布时间】:2017-07-03 14:25:17 【问题描述】:我有一个 Express GET 请求,它从 Mongoose 查询中提取数据,对于返回的每个 doc
,外部函数对作为 x
传递的每个 doc
执行计算并返回结果,以便我可以将它们呈现在前端使用 Handlebars。理想情况下,我想执行我的计算calcA, calcB, calcC, calcD
,然后在为每个文档完成计算后,渲染test-env.hbs
模板。目前,当我调用它时,页面没有呈现,在日志中,一段时间后,它显示GET /test-env - - ms - -
,大概是因为回调卡在某个地方。
快速 GET 请求
var updates = require('./updates.js');
app.get('/test-env', function(req, res, next)
Market.find("marketname" : 'To Win')
.then(function(doc)
async.forEach(doc, function(x, callback)
updates.calcA(x);
updates.calcB(x);
updates.calcC(x);
updates.calcD(x);
, function(err)
if(err)
return console.log(err);
res.render('test-env', title: 'Test Page', items: doc);
);
);
);
典型的calc
函数
我想将returnA
和returnB
添加到docs
数据中,以便我可以在Handlebars 中的#each
表达式中呈现它
calcA: function(x)
Market.find("student": x.student, "marketname": x.marketname)
.sort(btotal: -1)
.limit(1)
.then(function(ret)
var valueA = ret[0].btotal;
var valueB = ret[0].back;
Market.find("student": x.student, "marketname": x.marketname, "back": $lt: valueB)
.sort(odds: -1)
.limit(1)
.then(function(doc)
var res = doc[0];
if (res == null)
x.returnA = 0;
x.returnB = 0;
else
x.returnA = res.back;
x.returnB = res.btotal;
);
);
【问题讨论】:
【参考方案1】:看起来你实际上并没有调用你的回调函数。
async.forEach(doc, function(x, callback)
updates.calcA(x);
updates.calcB(x);
updates.calcC(x);
updates.calcD(x);
// <--- callback() needs to go here.
看:http://caolan.github.io/async/docs.html#each 该示例显示您需要显式调用 callback() 函数。
顺便问一下,您的计算(和回调函数)是否取决于doc
集合的内容顺序?因为async.forEach
方法实际上并不能保证doc
中的每个元素都将按照它们在集合中的顺序进行计算。因此,如果您是,那么值得考虑无序计算是否会导致不同的结果。
【讨论】:
嘿,Jty.tan,updates.calc()
函数不使用任何回调,它们都包含两个嵌套的 mongoose 调用,使用 .then(function(res1))
用于外部 mongoose 查询,.then(function(res2))
用于内部 mongoose询问。 calc
函数的执行顺序无关紧要,只要在渲染页面之前完成四个。我用你的方法试过了,还是加载不出来。【参考方案2】:
您没有在异步迭代器中调用回调。如果calc
函数是异步的,则应单独处理这些回调。如果它们不是异步的,普通的forEach
就可以了。
...
async.forEach(doc, function(x, callback)
updates.calcA(x);
updates.calcB(x);
updates.calcC(x);
updates.calcD(x);
callback(); // Call the callback to move on to the next item
, function(err)
if(err)
return console.log(err);
res.render('test-env', title: 'Test Page', items: doc);
);
...
【讨论】:
嘿 carebdayrvis,updates.calc()
函数不使用任何回调,它们都包含两个嵌套的 mongoose 调用,使用 .then(function(res1))
用于外部 mongoose 查询,.then(function(res2))
用于内部 mongoose 查询。 calc
函数的执行顺序无关紧要,只要在渲染页面之前完成四个。我用你的方法试过了,还是加载不出来。
您提供的calcA
函数是异步的。如果您希望该功能在呈现页面之前完成,您必须异步处理它。一种方法是承诺。看看这些:exploringjs.com/es6/ch_promises.htmlcaolan.github.io/async/docs.html#series以上是关于NodeJS 异步回调未完成和渲染把手模板的主要内容,如果未能解决你的问题,请参考以下文章