When ever I run this code the content_2 function runs first instead of content_1. The code below runs asynchronously and the second function uses a variable in the first function through "node.js store" to run so I need content_2 to wait for content_1 to finish before it starts running, I want it to run synchronously.
const content_1 = function main_Content(req, res, callback) {
const assert = require('assert');
const fs = require('fs');
const mongodb = require('mongodb');
const mv = require('mv');
var filename = req.body.Filename + Math.ceil((Math.random() * 1000000000000) + 10);
console.log(req.body.Filename)
//CREATE A FILE
fs.writeFile(filename + '.html', req.body.Content, (err) => {
if (err) throw err;
console.log('File was created successfully...');
});
//MOVE TO UPLOADS
const currentPath = path.join(__dirname, "../", filename + ".html");
const destinationPath = path.join(__dirname, "../uploads", filename + ".html");
mv(currentPath, destinationPath, function(err) {
if (err) {
throw err
} else {
console.log("Successfully moved the file!");
}
});
const uri = 'mongodb://localhost:27017';
const dbName = 'registration';
const client = new mongodb.MongoClient(uri);
client.connect(function(error) {
assert.ifError(error);
const db = client.db(dbName);
var bucket = new mongodb.GridFSBucket(db);
//UPLOAD FILE TO DB THROUGH STREAMING
fs.createReadStream('./uploads/' + filename + '.html').
pipe(bucket.openUploadStream(filename + ".html")).
on('error', function(error) {
assert.ifError(error);
}).
on('finish', function(res) {
var result = res._id
store.set('id', result);
//process.exit(0);
});
});
}
const content_2 = function metaData(req, res, callback) {
const obj = new ObjectId()
var filename = req.body.Filename + Math.ceil((Math.random() * 1000000000000) + 10);
const slice = require('array-slice')
var id = store.get('id');
console.log(id)
var objID = slice(id, 14, 24)
console.log(objID + '2nd')
Key.findByIdAndUpdate(req.body.id, {$push: {Articles:{Title: req.body.Title, Desc:req.body.Desc, Content: {_id: `ObjectId("${objID}")`}}} }, (err, docs) => {
if(err){
console.log(err)
}else{
console.log('done' + obj)
}
});
}
I will give you two examples. First one will be using promises. Second one will be using async await. The output though is exactly the same.
Supose those three methods. Someone cleans a room, "then" someone checks if the room is clean, "then" a payment is done.
Promises version
const cleanRoom = new Promise((res, rej) => {
console.log("Cleaning room...");
setTimeout(() => {
console.log("Room clean!");
res();
}, 2000);
});
const cleanCheckup = () => {
return new Promise((res, rej) => {
console.log("Clean checkup...");
setTimeout(() => {
console.log("Checkup complete!");
res();
}, 2000);
});
}
const payMoney = () => {
console.log("Open Wallet!");
return new Promise((res, rej) => {
setTimeout(() => {
res("50€");
}, 2000);
});
}
cleanRoom
.then(cleanCheckup)
.then(payMoney)
.then(console.log);
Async/Await version
const sleep = mils => {
return new Promise(r => setTimeout(r, mils));
};
const cleanRoomAW = async () => {
console.log("Cleaning room...");
await sleep(2000);
console.log("Room clean!");
};
const cleanCheckupAW = async () => {
console.log("Clean checkup...");
await sleep(2000);
console.log("Checkup complete!");
};
const payMonney = async () => {
console.log("Open Wallet!");
await sleep(2000);
return "50€";
};
async function run() {
await cleanRoomAW();
await cleanCheckupAW();
const value = await payMonney();
console.log(value);
};
run();
Please be aware of the helper method sleep, since you can't await for setTimeout in the browser yet. (In node js >=16 I believe you dont need this helper method).
You can copy/paste any of the two versions into the browser's console and confirm that both versions run synchronously despite the asynchronous nature of the setTimeout.