Обновить сообщение в представлении после того, как представление было отображено в экспрессе (после выполнения асинхронного кода) - PullRequest
0 голосов
/ 16 декабря 2018

Я создаю небольшое экспресс-приложение, которое в основном просто читает файлы из каталога, переименовывает их, а затем архивирует файлы, теперь часть файлов для чтения и переименования выполняется синхронно, часть архивирования выполняется асинхронно, а затем мое приложение.отображает другое представление, поэтому моя логика выглядит примерно так:

/*
    // 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 только один раз.), поэтому после того, как все обещания были выполнены, я действительно хотел бы продолжить и вывести новое сообщение в виде.Как мне это сделать?

1 Ответ

0 голосов
/ 16 декабря 2018

Вы правы, что не можете отправить несколько res.render.В стандартном HTTP клиент ожидает получить фиксированную длину контента, и вы не сможете изменить его позже при отправке.

Обычно, когда вы хотите добиться чего-то подобного, ваш клиент должен отправитьвторой запрос, который блокируется, пока сервер действительно не выполнит свои асинхронные действия.Вы могли бы использовать соединение через веб-сокет или что-то очень сложное, но вот небольшой пример, использующий способность 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...