natergj / excel4node

Node module to allow for easy Excel file creation
MIT License
1.38k stars 215 forks source link

wb.write() is asynchronous but does not return a promise #293

Open daweimau opened 5 years ago

daweimau commented 5 years ago

Where no handler is provided to wb.write(), the current method uses native fs to write to the buffer:

fs.writeFile(fileName, buffer, function (
    if (err) {
        throw err;
    }
});

But fs works asynchronously. It can be implemented to return a promise: see discussion here.

Currently, wb.write() is non-blocking (good), but it should be returning a void promise so that we can await write completion, and not attempt to operate on the file until it is actually written.

I would submit a PR but I'm not confident enough. In my implementation I just recreated the wb.write() method entirely, but correctly awaiting the fs writeFile result. This works correctly for me:

const buffer = await wb.writeToBuffer();
await fs.writeFile(outPath, buffer, function(err) {
    if (err) {
        throw err;
    }
});

EDIT: On review, I am not sure my implementation above works properly. But the problem is real.

metawrap-dev commented 3 years ago

This is a major issue for me. Need write to be async OR the ability to perform a blocking flush/close.

A the moment when generating a report and exiting process.exit(-1); the workbook is not written.

SimeonRolev commented 3 years ago

@natergj Definitely a major issue here.

mellowcello77 commented 3 years ago

Is there a wokaround? How else would you wait for a file to be written before downloading it?

SimeonRolev commented 3 years ago

Is there a wokaround? How else would you wait for a file to be written before downloading it?

@mellowcello77 , @daweimau provided a workaround in this initial question. He writes synchronously to a buffer await wb.writeToBuffer(); and then uses the default await fs.writeFile which is also synchronous.

mellowcello77 commented 3 years ago

Is there a wokaround? How else would you wait for a file to be written before downloading it?

@mellowcello77 , @daweimau provided a workaround in this initial question. He writes synchronously to a buffer await wb.writeToBuffer(); and then uses the default await fs.writeFile which is also synchronous.

Thank you for clarifying that for me so quickly, it does actually work, just tested 👍🏻