When running the following code tidied in functions or not, it still writes to my file incorrectly. One thing that did work was wrapping those functions inside of a setTimeout method, with the seconds somewhere around 10. I just didn't like the idea of hardcoding those values and taking anymore time to complete than it should. What's a better way of going about this? I need help understanding async/await a little more as you can tell but what better way than to fail and ask for help!
genPriceChangeScripts: async () => {
const priceScript = `...`;
const changeData = await get24hrChange();
const globalCmds = [];
const globalPol = [];
const filtered = changeData.filter(function (item) {
return (
!item.symbol.includes("BTCUSDT_") && !item.symbol.includes("ETHUSDT_")
);
});
async function scripts() {
filtered.forEach((e) => {
const data = e.symbol;
const change = priceScript.replace("CHANGE", data);
fs.writeFile(
`../scripts/price_change/${data.toLowerCase()}_price_change.sh`,
change,
function (err) {
if (err) return console.log(err);
}
);
});
console.log("scripts finished");
}
scripts();
async function commands() {
for (let i = 0; i < filtered.length; i++) {
var pushCmds = `"#($CURRENT_DIR/scripts/price_change/${filtered[
i
].symbol.toLowerCase()}_price_change.sh)"`;
globalCmds.push(pushCmds);
}
const commands = globalCmds.join("\n");
const cmdsWithComment = commands.concat("\n#CHANGE3");
fs.readFile("../binance.tmux", "utf-8", (err, data) => {
if (err) {
throw err;
}
const addCmds = data.replace("#CHANGE1", cmdsWithComment);
fs.writeFile("../binance.tmux", addCmds, (err) => {
if (err) {
throw err;
}
});
});
console.log("cmds finished");
}
commands();
async function pols() {
for (let i = 0; i < filtered.length; i++) {
const pushPol = `"\\#{${filtered[
i
].symbol.toLowerCase()}_price_change}"`;
globalPol.push(pushPol);
}
const pol = globalPol.join("\n");
const polWithComment = pol.concat("\n#CHANGE4");
fs.readFile("../binance.tmux", "utf-8", (err, data) => {
if (err) {
throw err;
}
const addPol = data.replace("#CHANGE2", polWithComment);
fs.writeFile("../binance.tmux", addPol, (err) => {
if (err) {
throw err;
}
});
});
console.log("pols finished");
}
pols();
return prompt.end();
},
The issue is that making a function async
doesn't make it automatically wait for anything asynchronous going on inside it
async
/ await
is syntax "sugar" for working with Promises, and Promises only
So, if you use the promise version of writeFile/readFile like so
import * as fs from 'fs/promise';
you can write your code as follows
genPriceChangeScripts: async() => {
const priceScript = `...`;
const changeData = await get24hrChange();
const globalCmds = [];
const globalPol = [];
const filtered = changeData.filter(function (item) {
return (!item.symbol.includes("BTCUSDT_") && !item.symbol.includes("ETHUSDT_"));
});
async function scripts() {
const promises = filtered.map((e) => {
const data = e.symbol;
const change = priceScript.replace("CHANGE", data);
return fs.writeFile(`../scripts/price_change/${data.toLowerCase()}_price_change.sh`, change);
});
await Promise.all(promises);
console.log("scripts finished");
}
await scripts();
async function commands() {
for (let i = 0; i < filtered.length; i++) {
var pushCmds = `"#($CURRENT_DIR/scripts/price_change/${filtered[i].symbol.toLowerCase()}_price_change.sh)"`;
globalCmds.push(pushCmds);
}
const commands = globalCmds.join("\n");
const cmdsWithComment = commands.concat("\n#CHANGE3");
const data = await fs.readFile("../binance.tmux", "utf-8");
const addCmds = data.replace("#CHANGE1", cmdsWithComment);
await fs.writeFile("../binance.tmux", addCmds);
console.log("cmds finished");
}
await commands();
async function pols() {
for (let i = 0; i < filtered.length; i++) {
const pushPol = `"\\#{${filtered[i].symbol.toLowerCase()}_price_change}"`;
globalPol.push(pushPol);
}
const pol = globalPol.join("\n");
const polWithComment = pol.concat("\n#CHANGE4");
const data = await fs.readFile("../binance.tmux", "utf-8");
const addPol = data.replace("#CHANGE2", polWithComment);
await fs.writeFile("../binance.tmux", addPol);
console.log("pols finished");
}
await pols();
return prompt.end();
},
You need to await
the File System operations in order to wait for the asynchronous functions to return a response before proceeding.
await fs.readFile
and await fs.writeFile
See this question for further explanation and examples.
This is in addition to adding await
to your other async
functions to propagate the promise chain correctly.
Not that I'm saying all your code works, but here are the kind changes I would make to get you in the correct direction:
// code above
function scripts(){
const a = [];
filtered.forEach(e=>{
const data = e.symbol, change = priceScript.replace('CHANGE', data);
a.push(new Promise((resolve, reject)=>{
fs.writeFile(`../scripts/price_change/${data.toLowerCase()}_price_change.sh`,
change,
err=>{
if(err){
reject(err);
}
else{
resolve();
}
}
);
}));
});
return Promise.all(a);
}
await scripts();
// code below
Well... actually I would define the function somewhere else or not use it at all, but I think this is what you need to see.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.