【问题标题】:Do async work to set properties of an object inside a forEach and then return the object once all async work is done执行异步工作以在 forEach 中设置对象的属性,然后在完成所有异步工作后返回该对象
【发布时间】:2021-04-20 22:05:09
【问题描述】:

我正在尝试编写一些代码,允许我遍历数组并为数组中的每个元素执行一些异步工作。这个想法是执行异步工作,从中获取一个值,然后将对象的属性设置为该值,然后继续下一个。完成后,我想返回结果对象。

问题是我的异步代码不能正常工作,在运行任何异步代码之前返回了未初始化的变量。我也不完全确定 forEach 之前的 await 是否在做任何事情。

generate(): Promise<Properties>{
        return new Promise<Properties>(async resolve => {
            let columns = this._propertyDefinitionRepo.columnNames;
            let properties: Properties;
            await columns.map(async columnName => {
                return new Promise<void>(async resolve => {
                    let distinctValues = await this.doAsyncWork(columnName);
                    properties[this.columnNameToPropertyName(columnName)] = 
                         this.buildPropertyDefinition(columnName, distinctValues);
                    resolve();
                })
            });
            resolve(properties);
        })
    }

【问题讨论】:

  • 这是打字稿,不是吗?您可能希望添加该标签。
  • 是的,添加了。谢谢。

标签: javascript typescript asynchronous


【解决方案1】:

你不应该在这里使用.map(),因为这将执行所有的回调,而不是等待每个代表一个已解决的承诺。

改为使用普通的for 循环,因此await 发生在外部函数上下文的上下文中。

最后,您正在使用 Promise 构造函数回调反模式。当你手头已经有一个承诺时,不要使用new Promise

所以:

async generate(): Promise<MonitorProperties>{
    let columns = this._propertyDefinitionRepo.columnNames;
    let properties: Properties;
    for (let columnName of columns) {
        let distinctValues = await this.doAsyncWork(columnName);
        properties[this.columnNameToPropertyName(columnName)] = 
                 this.buildPropertyDefinition(columnName, distinctValues);
    }
    return properties;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-29
    • 2015-08-02
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多