【问题标题】:Second async await function is not calling第二个异步等待函数未调用
【发布时间】:2019-02-12 22:44:39
【问题描述】:

我正在尝试先解压缩一个文件,然后等待该解压缩文件完成,然后再循环遍历每个文件并将其上传到 S3 存储桶。第一个函数unzipPromise 运行良好,所有内容都在正确的目录中解压缩,但uploadS3Promise 根本没有运行。我在这个过程中没有遇到错误,它只是运行并解压缩文件,从不触及uploadS3Promise 函数。

function unzipInput(file, client, project_number, oldpath, newpath) {
    path = `zips/${client}/${project_number}/${file}/`;
    function unzipPromise() {
        return new Promise((resolve, reject) => {
            fse.mkdirsSync(path);
            fs.rename(oldpath, newpath, err => {
                if (err) {
                    throw err;
                }
            });
            fs.createReadStream(newpath).pipe(unzip.Extract({ path }));
        });
    }
    function uploadS3Promise() {
        console.log("running");
        return new Promise((resolve, reject) => {
            // fs.unlinkSync(newpath);
            fs.readdirSync(newpath).forEach(file => {
                uploadToS3(file, client, project_number, path);
                console.log(file, "test");
            });

            if (err) reject(err);
            else resolve("success");
        });
    }
    // New code with async:
    (async () => {
        try {
            await unzipPromise();
            await uploadS3Promise();
        } catch (e) {
            console.error(e);
        }
    })();
}

【问题讨论】:

  • 你永远不会在你的第一个承诺中调用resolve(),所以它会被永远等待。
  • uploadToS3 是异步的吗?如果没有,您的 uploadS3Promise 根本不应该创建承诺,因为它是完全同步的。

标签: javascript promise async-await fs


【解决方案1】:

uploadS3Promise 未运行,因为代码仍在等待 unzipPromise 完成。除非您 resolvereject 一个承诺,否则代码将不会进一步执行。

所以在你的代码中......

function unzipPromise(){
    ...
    resolve(...)
    ...
}

在不相关的注释中,我认为函数名称不以 promise 结尾会更易读。就像只是称他们为 unzip 和 uploadS3。我们通常不会通过返回类型来命名我们的函数,就像我们从不说 intIndexOf 等等。

【讨论】:

    【解决方案2】:

    你应该在解压路径完成后调用resolve,如果发生错误,你应该调用reject。 而且由于流是 EventEmitter,你可以监听事件并与之交互

    const stream = fs.createReadStream(newpath).pipe(unzip.Extract({ path }))
    stream
    .on('error', (err) => reject(err))
    .on('finish', () => resolve())
    

    【讨论】:

      【解决方案3】:

      就我个人而言,我会使用 .then 来稍微分解一下流程。

      unzipPromise().then(res => {
          console.log('resolved promise 1');
          uploadS3Promise();
      } rej => {
          console.log('rejected promise 1, sorry!');
      });
      

      另外——“unzipInput”永远不会被解析或拒绝。

      【讨论】:

      • 如果promise 永远得不到解决会有什么不同? ascyn-awaitthen 瀑布回调更好地处理承诺。
      • 我建议使用 .then,因为根据我的经验,它们更容易调试。他们不必留下来,但关键是您可以在流程的每个步骤中使用 console.log 并找到中断。你可以对 await 做同样的事情,但是你需要将它分配给一个 var 并检查它。老实说,第一个等待永远不会返回,它会永远等待。
      • 使用.then,我们默认创建变量和回调函数。如果需要从 for 循环中调用 async 函数,.then() 也无济于事。喜欢async { for loop result.push(await multipleCalls) }。谈论调试它只是一个习惯使用的东西。我从callbackasync.jspromise and .then()async-await 最后是generators。我最喜欢generators
      • 啊,是的,直到今天我才知道await 的存在。所以.then 对我来说似乎更自然。我希望我在编写最后一个应用程序时知道这一点! xD
      • 我不敢相信人们会如此迅速地否决一个答案(尽管这是理所当然的),但我写了一些非常好的其他答案(并且很可能帮助了用户因为他们没有写回任何东西),也没有人愿意投票。来吧,我只是想要一些代表!被否决的答案是否会影响用户?
      猜你喜欢
      • 2020-10-30
      • 1970-01-01
      • 2019-08-23
      • 2022-01-07
      • 1970-01-01
      • 2023-03-13
      • 2023-02-10
      • 2021-10-02
      • 2017-04-06
      相关资源
      最近更新 更多