有没有办法在不阻塞服务器的情况下运行 D3.js 以响应使用 Node/Express 的 http 请求?

mok*_*oki 6 javascript node.js express jsdom d3.js

我已经使用 d3.js 在服务器上使用 node 和 jsdom 生成 svg/html。我还测试了在 Web 请求中在服务器上使用 d3 来生成动态 svg/html,然后在模板/视图 (ejs) 中使用。这样做的问题是任何重要的 d3.js 代码都会阻塞服务器并强制额外的 Web 请求等待,直到生成 svg/html。有没有办法在不阻塞服务器的情况下使用 nodejs/express 中的 d3 在 Web 请求中生成动态 svg/html?

我想知道是否有一种异步方式来编写 d3,或者是否有一种方法可以使用额外的工作人员以一种避免阻塞的方式使用 d3(和 jsdom)生成 svg/html。

以下是一些可能希望在服务器而不是客户端上执行此操作的原因:预渲染 svg/html 并在快速模板中使用它将为用户提供统一的页面加载,而不会出现 svg/html 的“flash”在页面加载后绘制,就像在客户端中使用 d3 一样。您还可以避免向浏览器发送大量数据,并且可以保持 d3 代码的专有性。

这是一个基本示例,我的意思是在快速路由中使用 d3,这可能会阻止服务器接收其他传入的 Web 请求。

app.get("/", async function(req, res) {
    
    // get dynamic data from database based on req.query
    let data = await dbConnection.query(dynamic_sql)

    // create simulated DOM using jsdom. This step will block server.
    const { document } = (new JSDOM(``)).window;

    // use d3 to draw svg. This step will block server.
    let selection = d3.select(document).select("body")
    
    selection.selectAll("circle")
    .data(data).enter()
    .append("circle").attr("r", 5).attr("cx", 10).attr("cy", 10)

    // extract svg string
    let svgString = selection.node().innerHTML

    // pass svgString to template to render page for client
    res.render("/", {svgString: svgString})

}
Run Code Online (Sandbox Code Playgroud)

如果您有任何想法,请告诉我!