簡體   English   中英

如何等待 function 完成后再運行另一個或 rest 的代碼?

[英]How to wait for function to finish before running another one or rest of the code?

我想不通這個。 我有一個 function 連接到 SFTP 服務器並下載文件。 然后,我有第二個 function 讀取內容,將數據放入數組中,然后返回數組。

問題是第二個 function 總是先運行。 我嘗試了不同的方法,但我無法讓它工作。 與 SFTP 的連接非常慢,可能需要 10 多秒才能完成。 但我需要以某種方式等待它完成,然后再做任何其他事情。

const SFTPConfig = require('../config/keys').sftpconfig;

const getCSATFiles = async function(targetDate) {
  try {
    let Client = require('ssh2-sftp-client');
    let sftp = new Client();
    const date = moment(targetDate);

    var dir = `../csv/${targetDate}/`;

    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir);
    }

    sftp
      .connect(SFTPConfig, 'once')
      .then(() => {
        return sftp.list('/In/Archives/');
      })
      .then(data => {
        data.forEach(item => {
          const fileName = item.name;
          const remotePath = '/In/Archives/' + fileName;

          const localePath = path.join(dir + fileName);

          if (
            moment(item.modifyTime)
              .format('YYYY-MM-DD hh:mm')
              .toString()
              .slice(0, 10) ===
            date
              .format('YYYY-MM-DD hh:mm')
              .toString()
              .slice(0, 10)
          ) {
            sftp
              .fastGet(remotePath, localePath, {})
              .then(() => {
                console.log('finished getting the files!');
                sftp.end();
              })
              .catch(err => {
                sftp.end();
                console.log(err, 'fastGet method error');
              });
          }
        });
      });
  } catch (error) {
    console.log(error);
  }
};

const readCSVFiles = async function(targetDate) {
  try {
    const casesBO = [];

    var dir = `../csv/${targetDate}/`;

    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir);
    }

    const allLocalFiles = path.join(__dirname, dir);
    const readDir = util.promisify(fs.readdir);

    const files = await readDir(allLocalFiles);

    for (let file of files) {
      fs.createReadStream(allLocalFiles + file)
        .pipe(csv.parse({ headers: true, delimiter: ';' }))
        .on('error', error => console.error(error))
        .on('data', row => {
          if (row['[REGION2]'] !== 'FR') {
            casesBO.push(row['[CALLERNO_EMAIL_SOCIAL]']);
            console.log(
              `${row['[AGENT]']} is ${row['[REGION2]']} and case = ${
                row['[CALLERNO_EMAIL_SOCIAL]']
              }`
            );
          }
        })
        .on('end', rowCount => {
          console.log(`Parsed ${rowCount} rows`);
        });
    }
    return casesBO;
  } catch (error) {
    console.log(error);
  }
};

const testFunc = async () => {
  const csatfiles = await getCSATFiles('2021-02-03');

  const boData = await readCSVFiles('2021-02-03');
  console.log(boData);
};
testFunc();

#1 正如@messerbill 建議的那樣,您需要從 function 中返回 promise。 #2 你的 promise 里面有一個循環,它有更多的承諾。 在這種情況下,您需要收集這些承諾並使用 Promise.all 來解決它們,然后再運行第二次 function。 我在下面需要更改的行上發表了評論。 嘗試這個:

const SFTPConfig = require('../config/keys').sftpconfig;

const getCSATFiles = function(targetDate) {
  try {
    let Client = require('ssh2-sftp-client');
    let sftp = new Client();
    const date = moment(targetDate);

    var dir = `../csv/${targetDate}/`;

    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir);
    }
    // I return the promise here
    return sftp
      .connect(SFTPConfig, 'once')
      .then(() => {
        return sftp.list('/In/Archives/');
      })
      .then(data => {
        // I set up my promises as a blank array
        const promises = [];
        data.forEach(item => {
          const fileName = item.name;
          const remotePath = '/In/Archives/' + fileName;

          const localePath = path.join(dir + fileName);

          if (
            moment(item.modifyTime)
              .format('YYYY-MM-DD hh:mm')
              .toString()
              .slice(0, 10) ===
            date
              .format('YYYY-MM-DD hh:mm')
              .toString()
              .slice(0, 10)
          ) {
            // I collect the promises here
            promises.push(sftp
              .fastGet(remotePath, localePath, {})
              .then(() => {
                console.log('finished getting the files!');
                sftp.end();
              })
              .catch(err => {
                sftp.end();
                console.log(err, 'fastGet method error');
              }));
          }
        });
        // I resolve them here
        return Promise.all(promises);
      });
  } catch (error) {
    console.log(error);
  }
};

const readCSVFiles = async function(targetDate) {
  try {
    const casesBO = [];

    var dir = `../csv/${targetDate}/`;

    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir);
    }

    const allLocalFiles = path.join(__dirname, dir);
    const readDir = util.promisify(fs.readdir);

    const files = await readDir(allLocalFiles);

    for (let file of files) {
      fs.createReadStream(allLocalFiles + file)
        .pipe(csv.parse({ headers: true, delimiter: ';' }))
        .on('error', error => console.error(error))
        .on('data', row => {
          if (row['[REGION2]'] !== 'FR') {
            casesBO.push(row['[CALLERNO_EMAIL_SOCIAL]']);
            console.log(
              `${row['[AGENT]']} is ${row['[REGION2]']} and case = ${
                row['[CALLERNO_EMAIL_SOCIAL]']
              }`
            );
          }
        })
        .on('end', rowCount => {
          console.log(`Parsed ${rowCount} rows`);
        });
    }
    return casesBO;
  } catch (error) {
    console.log(error);
  }
};

const testFunc = async () => {
  const csatfiles = await getCSATFiles('2021-02-03');

  const boData = await readCSVFiles('2021-02-03');
  console.log(boData);
};
testFunc();

您需要注意,您要在 function 主體內返回要解析的 promise,以便在正確的時間解析 promise。

 async function promiseNotReturned() { new Promise(resolve => setTimeout(resolve.bind(null), 5000)) } async function promiseReturned() { return new Promise(resolve => setTimeout(resolve.bind(null), 5000)) } async function run() { await promiseNotReturned() console.log("does not wait for 5 seconds") await promiseReturned() console.log("waits for 5 seconds") } run()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM