【问题标题】:Update message in view after view has been rendered in express ( once asynchronous code is executed )在以 express 呈现视图后更新视图中的消息(一旦执行异步代码)
【发布时间】:2018-12-16 10:01:45
【问题描述】:

我正在构建一个小型快速应用程序,它基本上只是从目录中读取文件重命名它们然后压缩文件,现在文件的读取和重命名部分同步完成,压缩部分异步完成,然后我的应用程序呈现另一个视图,所以我的逻辑如下:

/*
    // file read and renaming code here
 */

// Zip files code below:

try {
        let files_converted = fs.readdirSync(OUTPUT_DIRECTORY);
        let file_converstion_async_array = [];

        files_converted.forEach( (e , i) => {
            file_converstion_async_array.push( () => zip_Directory( `${OUTPUT_DIRECTORY}/${e}` ,  `${OUTPUT_DIRECTORY}/${e}.zip` ) );
        });

        console.log('Files are being zipped...');        

        file_converstion_async_array.reduce( ( promise_chain , current_promise ) => {

            return promise_chain.then( p_results => {
                return current_promise().then( c_result => {
                    // console.log('ZIPPED');
                });
            });

        } , Promise.resolve([]) ).then( () => {
            console.log('All Files have been zipped...');
        });

    } catch (err) {
        console.error(err);
    }

  // Finally render a new view 

    res.render("finish", {
       name: req.body.outputPath
    });

现在发生的是同步代码运行,然后呈现新视图,然后异步代码继续在后台运行。我想做的是,一旦执行异步代码以使用新消息更新我的视图,我怎么能在不显示另一个新视图的情况下做到这一点(我不确定这是可能的,因为我试过了,我相信你只能使用一次res.render。),所以在所有的承诺都被执行之后,我真的很想继续在视图中呈现一条新消息。我该怎么做呢?

【问题讨论】:

    标签: javascript node.js express


    【解决方案1】:

    关于无法发送多个res.render 是正确的。在标准 HTTP 中,客户端期望接收固定的内容长度,并且您稍后在发送时将无法更改它。

    通常,当您想要实现这样的事情时,让您的客户端发送第二个请求,该请求会阻塞,直到服务器真正完成其异步操作。您可以使用 websocket 连接或非常复杂的东西,但这里有一个利用 express 动态使用路由的能力的小示例:

    const express = require("express");
    const app = express();
    
    let jobs = {};
    
    app.get("/jobs/:number.js", (req, res) => {
      const jobNr = req.params.number;
      const job = jobs[jobNr];
      if (!job) {
        console.log("no job found!");
        return res.sendStatus(404);
      }
    
      job
        .then(result => res.send(`document.getElementById("result-${jobNr}").innerHTML = "job ${jobNr} is done with ${result}";`))
        .catch(err => res.sendStatus(500))
        .then(() => {
          // finally clean up, as some client requested this resource
          jobs[jobNr] = null;
        });
    });
    
    app.get("/", (req, res) => {
    
      // set up a job with whatever is necessary to do
      const jobNr1 = Math.floor(Math.random() * 10000000);
      const job = new Promise(resolve => setTimeout(() => resolve("a result!"), Math.random() * 5000 + 2000));
      jobs[jobNr1] = job;
    
      // set up a second job with whatever is necessary to do
      const jobNr2 = Math.floor(Math.random() * 10000000);
      const job2 = new Promise(resolve => setTimeout(() => resolve("another result!"), Math.random() * 5000 + 2000));
      jobs[jobNr2] = job2;
    
      res.send(`<!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8"/>
    <title>test</title>
    </head>
    <body>
      <div id="result-${jobNr1}">job ${jobNr1} running...</div>
      <div id="result-${jobNr2}">job ${jobNr2} running...</div>
      <script async src="/jobs/${jobNr1}.js"></script>
      <script async src="/jobs/${jobNr2}.js"></script>
    </body>
    </html>
    `);
    });
    
    app.listen(8080);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-25
      • 2019-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多