异步并行的要求 - 部分渲染 [英] async parallel request - partial render

查看:126
本文介绍了异步并行的要求 - 部分渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是正确的方式来部分呈现视图下一个异步并行请求?

What is the proper way to partially render a view following an async parallel request?

目前我做以下

// 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'});

});

它基本上是工作正常,但如果我有一个功能1,功能2,...,功能N 视图将只呈现时最慢的功能都将完成

It is basically working fine, but, if I have a function1, function2, ..., functionN the view will be rendered only when the slowest function will have completed.

我想找到正确的方法,以便能够尽快为他们可尽快渲染视图作为第一个函数返回,以尽量减少用户的延迟,并添加函数的结果。

I would like to find the proper way to be able to render the view as soon as the first function is returning to minimise the user delay, and add the results of the function as soon as they are available.

推荐答案

你想要的是Facebook的bigpipe:的 https://www.facebook.com/note.php?note_id=389414033919 。幸运的是,这是容易因的NodeJS流是内置的。不幸的是,模板系统是在这个糟糕的,因为异步模板是一个痛苦的对接。然而,这比做任何其他AJAX请求好得多。

what you want is facebook's bigpipe: https://www.facebook.com/note.php?note_id=389414033919. fortunately, this is easy with nodejs because streaming is built in. unfortunately, template systems are bad at this because async templates are a pain in the butt. however, this is much better than doing any additional AJAX requests.

基本思路是首先发送一个布局:

basic idea is you first send a layout:

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>'))
})

您不能发送&LT; /身体GT;&LT; / HTML&GT; ,因为您的文档还没有完成。那么 writePartials 将是一堆并行执行异步函数(谐音或小页)。

you can't send </body></html> because your document isn't finished. then writePartials would be a bunch of async functions (partials or pagelets) executed in parallel.

function writePartials(callback) {
  async.parallel([partial1, partial2, partial3], callback)
})

请注意:既然你已经写好的响应,有没有什么可以与除记录他们的错误做

Note: since you've already written a response, there's not much you can do with errors except log them.

每个部分是什么会做派是内联JavaScript客户端。例如,布局可以有 .stream ,和小网页将取代的 .stream 的innerHTML 抵达时,或者当回调结束。

What each partial will do is send inline javascript to the client. For example, the layout can have .stream, and the pagelet will replace .stream's innerHTML upon arrival, or when "the callback finishes".

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()
  })
})

就个人而言,我有 .stream.placeholder 并用新的 .stream 元素替换它。原因是我基本上做到 .placeholder,.placeholder〜* {显示:无} 这样的事情不要在页面跳来跳去。然而,这需要一个DIY的前端框架,因为突然被JS更complciated。

Personally, I have .stream.placeholder and replace it with a new .stream element. The reason is I basically do .placeholder, .placeholder ~ * {display: none} so things don't jump around the page. However, this requires a DIY front-end framework since suddenly the JS gets more complciated.

有,你的反应是现在流。唯一的要求是,客户端支持JavaScript。

There, your response is now streaming. Only requirement is that the client supports Javascript.

这篇关于异步并行的要求 - 部分渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆