当一个页面有多个数据块的时候,后台一般是怎么写的?
发布于 11 年前 作者 yakczh 4605 次浏览 最后一次编辑是 8 年前

是挨个嵌套调用吗,然后在最内层render 模板吗?

4 回复

多个数据块之间有依赖吗?

平行关系的多个数据块,再模板里单独render就行。

比如这个贴子的页面,左面是贴子,右面是用户信息, 两者没有依赖关系,你说的单独render是这样吗?

 var post = require('../models/post.js');
 
 post.findOne({_id:xxx},function(err,post)){
  
  res.render('topic',{post:post});
 
 }
 
  var user = require('../models/user.js');
 
 post.findOne({_id:xxx},function(err,info)){
  
  res.render('topic',{info:info});
 
 }

肯定不是这样的啊,如果是ejs模板,你可以用include ,你要等到把数据都拿到了才调用render,或者前头异步加载

这个问题抽象出来就是nodejs的异步流控制(Asynchronous Control Flow),楼主所关心是属于其中的并行流。成熟的解决方案有async,step,promise之类的,自行google。顺带一提,cnodejs的社区论坛是用eventproxy。 如果不想引入额外的模块,自行折腾一个也不难。论坛这篇文章JS异步流程控制(序列模式、并发模式、有限并发模式)应该对你有所启发。考虑伸手党,附上我自己曾经用过一种方法的:

function parallel(limit, done) {
  if (typeof limit == 'function') {
    done = limit, limit = 0;
  }
  var jobs = [], results = [], i = 0;
  var dones = 0; //total number of finished job
  function next(n) {
    if (dones === jobs.length) done(results);
    for (var j = 0; j < n && i < jobs.length; j++, i++) {
      jobs[i](function (pos) {
        dones++;
        results[pos] = [].slice.call(arguments, 1);
        next(1);
      }.bind(null, i));
    };
  }
  process.nextTick(function () {
    //run next <limit> jobs. if limit=0, run all the jobs
    next(limit || jobs.length);
  });
  return {
    do : function (job) { jobs.push(job); return this; }
  };
}
var post, info;
var task = parallel(function (results) {
  res.render('topic', { post: post, info: info });
});
task.do(function (done) {
  post.findOne({ _id: xx }, function (err, _post) {
    post = _post; done();
  });
});
task.do(function (done) {
  post.findOne({ _id: xx }, function (err, _info) {
    info = _info; done();
  });
});
回到顶部