I am implementing https.request per these instructions (https://nodejs.org/api/https.html#httpsrequesturl-options-callback) except instead of doing a stdout, I am writing to file. I want the end to wait until the file writing process is complete. How can I do this?
process.stdout.write(d);
is changed to
fs.writeFile(path, d, err => {
if (err) {
console.error(err);
} else {
console.log("data => " path)
}
})
This is the entire code
const https = require('node:https');
const options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET'
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();
UPDATE
MTN posted a solution that works, but I realized that my code is slightly more complex. I read the file in chunks and save at the end. MTN's solution finishes early. Here is the code. Can anyone help me fix it?
const request = https.request(url, (response, error) => {
if (error) {console.log(error)}
let data = '';
response.on('data', (chunk) => {
data = data chunk.toString();
});
response.on('end', () => {
fs.writeFile(path, data, err => {
if (err) {
console.error(err);
} else {
console.log("data => " path)
}
})
})
})
request.on('error', (error) => {
console.error(error);
})
request.end()
},
CodePudding user response:
You can use fs.writeFileSync()
instead. Its sync so it waits for the writing to be finished
CodePudding user response:
The immediate answer would be that whatever should happen after the file was written would have to go into the callback, after your console.log
. (There is nothing in your code that looks like it's supposed to run afterwards though.)
But:
Your code would be a lot simpler if you'd...
Use a library for sending HTTP requests instead of the raw
https
module. (For example:got
,axios
,node-fetch
, ...) - Not only do these take care of things like reading the body for you, they also have a promise interface which allows you to do point 2.Rewrite the code to uses
async
/await
.
Here is an example with got
:
import got from 'got'
import { writeFile } from 'fs/promises'
const response = await got('https://encrypted.google.com').text()
await writeFile('test.html', response)
// Whatever should happen after the file was written would simply go here!
Note: This has to be an ES6 module because I used top-level await
and import
, and got
doesn't even support CommonJS anymore. So either your package.json
would have to have "type": "module"
or the file ending would have to be mjs
.
CodePudding user response:
res.on(“data”, (d) => { fs.writeFile(/* Enter params here */ })
Inside the fs.writeFile, add whatever you want to do in the last callback function.