const axios = require("axios");
const fs = require("fs").promises;
const second = async () => {
console.log('++')
}
const processData = async () => {
const req = await axios.get('http://google.com');
let reqJson = JSON.stringify(req.data);
try {
await fs.writeFile('newSwagger.json', reqJson);
console.log('succesful');
} catch (e) {
throw e;
}
}
let firstPromise = new Promise (function (resolve, reject) {
second().then(processData).then(resolve);
});
firstPromise.then(second)
.then(() => console.log('finished'));
results in
++
successful
++
finished
Explanations
second
is a parameterless function that returns a promise. It isn't itself a promise. This means that when you're doing second(() => resolve(processData()))
, you're never actually invoking the processData function. You're just executing the second
function and handing it a function that would run processData
but instead it never executes the passed in function as something like this would:
const second = async (callback) {
callback()
}
Also the async
keyword for second
is unnecessary since you're not using an await
within. The async
keyword basically is syntactic sugar which wraps the function into returning a promise kind of like:
const second = () => {
console.log('++')
return new Promise();
so in my corrected example, that's why I can suddenly do second().then(doSomething)
however because there's nothing awaited within, it's the exact same as just second()
followed by doSomething()
.
Also, the resolve
inside of new Promise((resolve, reject) => ...)
is kind of like setting a return
, but it doesn't necessarily wait for anything. So if you want the second '++' to wait until processData
is completely done and 'successful' is logged, you need to chain off the processData's returned promise like .then(processData).then(resolve)
.
Finally if you do the above, you may still notice that you don't see your 'successful' string printed - or well you might sometimes and at unexpected times. This is because you've also added callbacks into the mix along with promises and async/await. the ultimate effect being that your console.log('successful') will run at some point but you have nothing waiting for it nor chained after it. You could promisify the call to fs.writeFile
yourself but you could also just use the built-in promise version of node's fs
module - see this for more.
If it helps focus only on how the promises work(without async/await and callbacks also), here's a version with only promises to achieve the same resulting output:
const axios = require("axios");
const fs = require("fs").promises;
const second = () => {
console.log('++')
}
const processData = () => {
return new Promise(
resolve => axios.get('http://google.com').then((req) => {
let reqJson = JSON.stringify(req.data);
return reqJson;
}).then((reqJson) => {
fs.writeFile('newSwagger.json', reqJson).then(resolve);
}).then(() => console.log('successful'))
);
}
second();
processData().then(() => {
second();
console.log('finished')
})