【问题标题】:Method returning promise is not fully executed despite using await keyword?尽管使用了 await 关键字,但返回 promise 的方法没有完全执行?
【发布时间】:2016-11-08 03:26:21
【问题描述】:

我是 JavaScript 新手,并且正在积极学习。我正在调用一个方法,该方法使用 await 关键字从 ES2016 类的异步方法中返回一个 Promise:

        export default class MyClass extends Model {
            async getReport() {
                const value = await xlsx.save(await this._getReportFileName());
                console.log('await keyword returned method value');
                console.log(`The value is: ${value}`);
                return true;
            }
        }

任何人都可以在该方法有机会执行其逻辑之前以及在调用 resolve 之前找出执行该方法的原因。 await 关键字似乎没有等待 promise 实际返回,并且输出到控制台的值是未定义的。

Object xlsx 是类 File 的一个实例,它有一个方法 save:

export default class File {
    save(filename, options) {
        writer.save(this, filename, options);
    }
}

这里是调用保存辅助方法的代码:

function save(xlsx, filename, options) {
    return new Promise((resolve, reject) => {
        try {
            const stream = fs.createWriteStream(filename, options);
            const zip = archiver('zip');

            stream.on('close', () => {
                console.log('Resolving promise');
                resolve();
            });

            stream.on('error', (err) => {
                console.log('Rejecting promise');
                reject(err);
            });

            zip.pipe(stream);

            const file1 = 'fixtures/file1.txt';
            const file2 = 'fixtures/file2.txt';

            zip
                .append(fs.createReadStream(file1), {
                    name: 'file1.txt'
                })
                .append(fs.createReadStream(file2), {
                    name: 'file2.txt'
                })
                .finalize();
        } catch (error) {
            console.log('Error when saving');
            reject(error);
        }
    });
}

难道 resolve() 在监听流事件的范围内甚至无法访问/可用吗?如果是这样,如何在侦听流事件时正确解决 Promise?

【问题讨论】:

  • 你能用 await 关键字说明你是如何调用它的吗?
  • 这不是因为你在箭头函数的 = 和 > 之间放了一个空格吗?当我尝试用空格声明箭头函数时出现错误
  • await 返回承诺的值,而不是承诺本身(假设您在 async function 中)。这就是重点。你得到undefined 因为你调用resolve() 没有值。
  • @EugeneV:您能解释一下您看到的哪些行为让您认为await 没有等待承诺解决吗?你的代码中有一堆日志语句:你能分享你实际看到的被记录到控制台的内容吗?
  • @StriplingWarrior,你明白了!!!!我编辑了我的问题以包含更多代码。我完全忽略了这样一个事实,即被调用的 save 方法是一个自定义对象的方法,该对象又调用了 helper 方法。只有辅助方法是异步的,而不是对象的方法。一直以来,我都在使用 await 关键字来解析一个非异步的方法,我傻了!!!如果您想获得积分,请指出问题,我将接受它作为正确答案。太感谢了!!!你无法想象我花了多少时间寻找解决方案。

标签: javascript node.js es6-promise


【解决方案1】:

您的save(filename, options) 传递方法不是异步的,它不会从save(xlsx, filename, options) 方法返回承诺。

试试这个:

export default class File {
    async save(filename, options) {
        await writer.save(this, filename, options);
    }
}

或者这个:

export default class File {
    save(filename, options) {
        return writer.save(this, filename, options);
    }
}

【讨论】:

  • 第一个也不能获取value变量,你需要return。可以使用return await,但那毫无意义。
  • @Bergi:就目前而言,writer.save() 方法的 Promise 永远不会用值解析,所以效果是一样的(即undefined)。但你是对的:如果在 zip.finalize() 完成后修改它以解析值,那么你需要 return await
猜你喜欢
  • 1970-01-01
  • 2019-07-09
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 2018-11-02
  • 2021-03-18
  • 1970-01-01
  • 2017-02-17
相关资源
最近更新 更多