简体   繁体   中英

Nodejs concurrent requests overridden variables

I have a method in nodejs used to generate a document. If I have two simultaneous requests, the content of one document is the same as the second one (the variable "contents" below). If for example the source.content retrieved by the first request should be "aaa" and the second is "bbb", the actual content of the file is "aaa" in both cases. If the requests are run sequentially, the content of the generated file is correct, "aaa" for the first request and "bbb" for the second.

public async generateDocument(req: Request, res: Response) {

        const sourceId = parseInt(req.params.id, 10);
        const source: ISource = await this.db.models.MoM.scope("full").findOne({ where: { sourceId : sourceId } });

        const signatureDate = getDateNow();
        // Load the docx file as a binary
        const content = fs.readFileSync(path.resolve(__dirname, "../../../../assets/Template.docx"), "binary");
        const zip = new PizZip(content);
        const doc = new Docxtemplater();
        doc.loadZip(zip);
        doc.setData({

            // @ts-ignore TODO: fix generic interfaces
            writer_name: "" + source.writer.displayedName,
            contents: source.content.split("\n").map((paragraph: string) => ({
                paragraph,
            })),

        });
        doc.render();
        const buf = doc.getZip().generate({ type: "nodebuffer" });
        const outputFilePath = path.resolve(__dirname, "../../../../assets/output.docx");
        fs.writeFileSync(outputFilePath, buf);
}

In your code, you do, at the end of the function

const outputFilePath = path.resolve(__dirname, "../../../../assets/output.docx");
fs.writeFileSync(outputFilePath, buf);

Which means that if the function is called twice, there is no way to know whether the generated file will be from the first call or the second call.

Probably, somewhere in your code, you are reading the /assets/output.docx file.

To solve your problem, I would instead return a Buffer from the generateDocument function, like this:

public async generateDocument(req: Request, res: Response) {
        // ...
        // ...
        doc.render();
        const buf = doc.getZip().generate({ type: "nodebuffer" });
        return buf;
}

And the caller of generateDocument should serve the buffer or do something with that (no need to write the file on the filesystem if you just want to let the user download it rightaway for example).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM