I'm coding website in node.js using express and socket.io. The server is sending to user photo and data from every file in directory using socket.emit function.
The problem with this code: The server is sending data from 2 files but image in second emit is same as first beacouse before sends first img is changing data of first file to second data.
I found this solution but it's not working. Some of the server side code:
function send(file) {
return new Promise((resolve, reject) => {
fs.readFile(dir file, 'utf8', (err, jsonString) => {
jsonString = JSON.parse(jsonString);
buffer = ""
img = false
img_path = dir jsonString.number
if (fs.existsSync(img_path '.jpg')) {
fs.readFile(img_path '.jpg', function (err, buf) {
buffer = buf
img = true
});
}
if (fs.existsSync(img_path '.png')) {
fs.readFile(img_path '.png', function (err, buf) {
buffer = buf
img = true
});
}
setTimeout(() => { // <---- Without wait buffer will be blank
console.log(img_path) //both times is same
data = {
number: jsonString.number,
image: img,
buffer: buffer.toString('base64')
}
socket.emit('data', data)
console.log("sended!")
resolve()
}, 100)
if (err) {
console.error(err);
return;
}
});
})
}
async function files() {
fs.readdir(dir, (err, files) => {
if (err) {
throw err
}
files.forEach(async file => {
if (file.split('.').pop() == 'json') {
await send(file)
}
})
})
}
files()
But this is not working. Thanks for help!
CodePudding user response:
There are a few misconceptions that have to addressed:
- async and sync flows used in same context, that's why you needed a
setTimeout
- async function in forEach doesn't do what you expect
- variable management, use
let
orconst
Some small things:
- argument passing,
dir
wasn't available in some contexts - async function definition for
send
For example your code could be rewritten like this:
Do note that I did not run this program
const { promisify } = require("util");
const readFile = promisify(fs.readFile);
const exists = promisify(fs.exists);
const readdir = promisify(fs.readdir);
async function getBuffer(filePath) {
const isFile = await exists(filePath);
if (!isFile) return;
return readFile(filePath);
}
async function send(dir, file) {
const content = await readFile(file, 'utf8');
if (!content) return;
const json = JSON.parse(content);
const img_path = dir json.number;
const buf1 = await getBuffer(`${img_path}.jpg`);
const buf2 = await getBuffer(`${img_path}.png`);
console.log(img_path);
const data = {
number: json.number,
image: buf1 || buf2,
buffer: (buf1 || buf2).toString('base64'),
}
socket.emit('data', data);
console.log("sended!");
}
async function files(dir) {
const files = await readdir(dir);
for (const file in files) {
if (file.split('.').pop() === 'json') {
await send(dir, file);
}
}
}
files("<directory>");