NodeJS asyn c функция для создания загрузчика страниц - PullRequest
0 голосов
/ 13 января 2020

Я знаю, что если у нас await в нашем async function, то функция будет приостановлена ​​до тех пор, пока не будет выполнено await, поэтому мне интересно, можем ли мы использовать время ожидания для создания загрузчика страниц? Если возможно, пожалуйста, помогите мне сделать это! Спасибо!

Мое приложение. js здесь:

const express = require('express');
const app = express();
const mongoose = require('mongoose');
require('dotenv/config');

// set up template engine;
app.set('view engine', 'ejs');

// static file; middleware;
app.use(express.static('public'));
app.use('/post', express.static('/public'));

// middleware;
const homeRoute = require('./controllers/home');
app.use('/', homeRoute);
const postsRoute = require('./controllers/posts');
app.use('/posts', postsRoute);


// connect to mongodb;
mongoose.connect(
    process.env.DB_CONNECTION,
    { useNewUrlParser: true},
    function(){
        console.log('Connected to db');
    }
);

// listen to port;
app.listen(3000);

И мои сообщений. js здесь:

const express = require('express');
const router = express.Router();
const Post = require('../models/posts');
const bodyParser = require('body-parser');
const urlencodedParser = bodyParser.urlencoded({extended: false});

router.get('/', function(req, res){
    res.render('post');
});
router.get('/post_render', async function(req, res){
    try {
        let post = await Post.find();             **HERE I WANT TO HAVE A PAGE LOADER**
        res.render('post_render', {data: post});  **DURING WAITING FOR THE DATA TO BE FOUND**
    } catch (err) {
        res.json({message: err});
    }

})

router.post('/', urlencodedParser, async function(req, res){
    let post = new Post({
        title: req.body.title,
        description: req.body.description
    });
    try {
        let savePost = await post.save(); // 
        res.redirect('/posts/post_render');  
    } catch(err){
        res.json({message: err});
    }
});

module.exports = router;

1 Ответ

3 голосов
/ 13 января 2020

Вращающийся круг в браузере, часто называемый «прядильщик» (что, по-видимому, вы подразумеваете под «загрузчиком страниц»), - это вещь на стороне клиента. Это должно быть реализовано на стороне клиента HTML или Javascript. Это может быть сделано на стороне клиента только для маршрутов, которые были запрошены из вызова Ajax в браузере, но не для маршрутов, которые были запрошены через перенаправление или прямую ссылку на новую страницу из браузера.

Проблема в том, что, как только браузер начинает запрашивать новую страницу, он очищает содержимое текущей страницы (поэтому вы не можете поместить спиннер в старую страницу). Содержимое новой страницы не отображается, пока достаточное количество новой страницы не будет обработано и не будет отображено HTML (оно отображается постепенно, как только поступает фрагмент автономного HTML, анализируется и не слишком зависит на другие ресурсы, которые еще не загружены.

Ваш текущий код делает это:

    let post = await Post.find();             **HERE I WANT TO HAVE A PAGE LOADER**
    res.render('post_render', {data: post});  **DURING WAITING FOR THE DATA TO BE FOUND**

Это означает, что в течение времени, когда вы хотите отобразить счетчик, вы не отправили ЛЮБОЙ HTML в браузер. Таким образом, все, что браузер сделает, это очистит предыдущую страницу и будет сидеть там с пустой страницей, ожидая поступления некоторого разбираемого HTML содержимого. Поскольку вы отправляете HTML только после поиска в вашей базе данных в браузер не поступит ничего, что могло бы показать счетчик. Таким образом, этот код, в том виде, в котором он написан, не сможет отобразить счетчик.

Вы можете показать счетчик во время вызова Ajax Страница хоста, показывающая счетчик, выполняет вызов Ajax и затем скрывает счетчик, когда вызов Ajax завершен.


* 10 12 * Я никогда не пробовал этого, но теоретически это возможно для этой последовательности:
  res.write(partA)
  let post = await Post.find();
  res.render('post_render', {data: post}, function (err, partB) {
      if (err) {
          res.write(partX);
      } else {
          res.write(partB);
      }
      res.end();
  });

В этом коде у вас будут следующие фрагменты HTML:

partA - первая часть страницы HTML, которая позволяла браузеру начать анализ страницы и отобразить счетчик (либо полностью с HTML, либо с HTML и Javascript). Это не может быть целая страница, это должна быть частичная, незаконченная страница, но что-то, что браузер считает безопасным для начала анализа и отображения, даже когда ожидает остальную часть страницы.

partB - Остальная часть HTML страницы, которая идет с partA. Это скроет предыдущий счетчик (вероятно, с Javascript), а затем предоставит оставшиеся HTML для страницы. partA + partB создаст полностью отформатированную, легальную HTML страницу.

partX - это альтернативная вторая часть страницы, которая идет с partA и будет отображаться при наличии ошибка рендеринга.


Другая возможность - ваш маршрут отправит полностью отформатированную страницу-заполнитель, которая показывает оболочку вашего контента и поднимает счетчик. На этой странице-заполнителе будет содержаться Javascript, который запрашивает фактические данные или обрабатывает HTML для страницы через Ajax вызов по другому маршруту. Когда вызов Ajax завершится успешно, ваш Javascript вставит этот контент на страницу и скроет счетчик. Это, вероятно, намного проще, чем идея partA / partB выше.

...