等待一项功能完成后再继续?

时间:2021-07-22 23:03:15

标签: javascript asynchronous

当运行以下代码在函数中整理或不整理时,它仍然错误地写入我的文件。有效的一件事是将这些函数封装在一个 setTimeout 方法中,秒数大约为 10。我只是不喜欢硬编码这些值并花费更多时间来完成的想法。 有什么更好的方法来解决这个问题?我需要帮助来理解 async/await,正如你所知道的那样,但还有什么比失败并寻求帮助更好的方法!

  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();
  },

3 个答案:

答案 0 :(得分:1)

问题是使函数 async 不会自动等待它内部发生的任何异步事件

async/await 是使用 Promises 的语法“糖”,并且 仅 Promises

所以,如果你像这样使用 writeFile/readFile 的 promise 版本

import * as fs from 'fs/promise';

您可以按如下方式编写代码

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();
},

答案 1 :(得分:0)

您需要await File System 操作,以便在继续之前等待异步函数返回响应。

await fs.readFileawait fs.writeFile

有关进一步的解释和示例,请参阅 this question

这是将 await 添加到其他 async 函数以正确传播承诺链的补充。

答案 2 :(得分:-2)

并不是说我的所有代码都可以工作,而是我会做出一些改变来让您朝着正确的方向前进:

// 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

嗯...实际上我会在其他地方定义函数或者根本不使用它,但我认为这是你需要看到的。