异步并行请求 - 部分渲染

4 asynchronous node.js express

在异步并行请求之后部分呈现视图的正确方法是什么?

目前我正在做以下事情

// an example using an object instead of an array
async.parallel({
    one: function(callback){
        setTimeout(function(){
            callback(null, 1);
            // can I partially merge the results and render here?
        }, 200);
    },
    two: function(callback){
        setTimeout(function(){
            callback(null, 2);
            // can I partially merge the results and render here?
        }, 100);
    }
},
function(err, results) {
    // results is now equals to: {one: 1, two: 2}
    // merge the results and render a view
    res.render('mypage.ejs', { title: 'Results'});

});
Run Code Online (Sandbox Code Playgroud)

它基本上工作正常,但是,如果我有一个function1, function2, ..., functionN视图将只在最慢的函数完成时呈现.

我希望找到一个正确的方法,以便在第一个函数返回时立即呈现视图以最小化用户延迟,并在函数可用时立即添加函数的结果.

Jon*_*Ong 5

你想要的是facebook的bigpipe:https://www.facebook.com/note.php? note_id = 389414033919 .幸运的是,这对于nodejs来说很容易,因为流是内置的.遗憾的是,模板系统很糟糕,因为异步模板很难对付.但是,这比执行任何其他AJAX请求要好得多.

基本的想法是你先发布一个布局:

res.render('layout.ejs', function (err, html) {
  if (err) return next(err)

  res.setHeader('Content-Type', 'text/html; charset=utf-8')
  res.write(html.replace('</body></html>', ''))

  // Ends the response. 
  // `writePartials` should not return anything in the callback!
  writePartials(res.end.bind(res, '</body></html>'))
})
Run Code Online (Sandbox Code Playgroud)

您无法发送,</body></html>因为您的文档尚未完成.然后writePartials是一堆并行执行的异步函数(partials或pagelet).

function writePartials(callback) {
  async.parallel([partial1, partial2, partial3], callback)
})
Run Code Online (Sandbox Code Playgroud)

注意:由于您已经编写了响应,因此除了记录错误之外,您无法解决错误.

每个部分将做的是向客户端发送内联JavaScript.例如,布局可以有.stream,和小网页将取代.streaminnerHTML到来时,或当'回调结束’.

function partialStream(callback) {
  res.render('stream.partial.ejs', function (err, html) {
    // Don't return the error in the callback
    // You may want to display an error message or something instead
    if (err) {
      console.error(err.stack)
      callback()
      return
    }

    res.write('<script>document.querySelector(".stream").innerHTML = ' + 
      JSON.stringify(html) + ';</script>')
    callback()
  })
})
Run Code Online (Sandbox Code Playgroud)

就个人而言,我有.stream.placeholder一个新.stream元素替换它.原因是我基本上这样.placeholder, .placeholder ~ * {display: none}做的事情不会跳到页面周围.然而,这需要一个DIY前端框架,因为突然JS变得更加复杂.

在那里,您的回复现在正在流式传输 唯一的要求是客户端支持Javascript.