如何在nodejs中编写非阻塞代码?我做错了什么?

huwehgph  于 2023-02-12  发布在  Node.js
关注(0)|答案(2)|浏览(122)

我有一个名为pdf的路由,如果我去的路线,它等待10秒,因为我创建了一个pdf和其他东西。但如果我去其他屏幕和pdf路由还没有完成,然后我的其他响应等待,我不能使用该网站,直到pdf路由完成。我怎么能不阻止响应?
PDF创建文件

var pdf = require("pdf-creator-node");
const path = require('path');
import fs from 'fs-extra';

export default async function PDFCreate() {
  try {
    var options = {
      format: "A3",
      orientation: "portrait",
      border: "10mm",
      header: {
          height: "0mm",
      },
      footer: {
          height: "28mm",
          contents: {
              first: 'Cover page',
              2: 'Second page', // Any page number is working. 1-based index
              default: '<span style="color: #444;">{{page}}</span>/<span>{{pages}}</span>', // fallback value
              last: 'Last Page'
          }
      }
  };
    console.log(path.join(__dirname));
    const html = fs.readFileSync('app/data/file.html', 'utf-8');
    const bitmap = fs.readFileSync('public/images/lg.jpeg');
    const logo = bitmap.toString('base64');
    const filename = Math.random() + '_doc' + '.pdf';

    const document = {
      html: html,
      data: {
        logo
      },
      path: './docs/' + filename
  }

    pdf.create(document, options)
    .then(res => {
        console.log(res);
    }).catch(error => {
        console.log(error);
    });

    const filepath = 'http://localhost:3000/public/images/' + filename;

    return filepath;
  } catch(e) {
    console.log(e);
    throw e;
  }
}

/PDF route(我使用了fullstack框架,所以加载程序与以下内容等效:路由. get('/s',(资源,请求)')

import PDFCreate from '~/data/createPDF.server'

export default async function loader() {
  try {
    await PDFCreate();
    return null;
  } catch(e) {
    console.log(e);
  }
}

/家

export default function Home() {
  return (
    <>
      <main className="container test">
        <p>test</p>
      </main>
    </>
  )
};

因此,当我调用/pdf并加载它时,如果我转到home route,则会加载我的home route,直到/pdf完成...我如何才能不阻止此操作?

jpfvwuh4

jpfvwuh41#

您可以尝试在使用AbortController卸载loader组件时使用abort执行。例如-

  • 首先将函数代码 Package 为promise并注册abort事件的回调。PDF创建文件
var pdf = require("pdf-creator-node");
      const path = require("path");
      import fs from "fs-extra";

          export default async function PDFCreate(abortSignal) {
              return new Promise(function (resolve, reject) {
                  // Wrap to promise

                  // register abort event
                  abortSignal.addEventListener("abort", () => {
                      // 6
                      const error = new DOMException(
                  "Calculation aborted by the user",
                  "AbortError"
              );
              reject(error); // 8
          });

          try {
              var options = {
                  format: "A3",
                  orientation: "portrait",
                  border: "10mm",
                  header: {
                      height: "0mm",
                  },
                  footer: {
                      height: "28mm",
                      contents: {
                          first: "Cover page",
                          2: "Second page", // Any page number is working. 1-based index
                          default:
                              '<span style="color: #444;">{{page}}</span>/<span>{{pages}}</span>', // fallback value
                          last: "Last Page",
                      },
                  },
              };
              console.log(path.join(__dirname));
              const html = fs.readFileSync("app/data/file.html", "utf-8");
              const bitmap = fs.readFileSync("public/images/lg.jpeg");
              const logo = bitmap.toString("base64");
              const filename = Math.random() + "_doc" + ".pdf";

              const document = {
                  html: html,
                  data: {
                      logo,
                  },
                  path: "./docs/" + filename,
              };

              pdf
                  .create(document, options)
                  .then((res) => {
                      console.log(res);
                      resolve(); // Resolve on success
                  })
                  .catch((error) => {
                      console.log(error);
                  });

              const filepath = "http://localhost:3000/public/images/" + filename;
              return filepath;
          } catch (e) {
              console.log(e);
              throw e;
          }
      });
    }
  • 现在在loader组件中初始化abortController,并在调用PDFCreate()函数时传递abortController。在卸载loader组件时调用abortController.abort(),也许在这里您可以使用特定于框架的组件生命周期方法,该方法. /PDF route

从“~/data/创建PDF.服务器”导入PDF创建;

export default async function loader() {
    let abortController = null;

    // Call abortController.abort when loader() component unmounts
    if (abortController) abortController.abort();

    try {
        abortController = new AbortController();
        await PDFCreate(abortController);
        return null;
    } catch (e) {
        abortController = null;
        console.log(e);
    }
  }
pdtvr36n

pdtvr36n2#

你有await PDFCreate();的一部分代码,这会让你的整个代码停止,等待PDFCreate()完成。这是单线程的,但是有一个修复程序,你可以在this question上阅读,你可以按照他们的建议使用node-worker,或者你可以尝试其他人的答案解决方案。

相关问题