【问题标题】:Synchronize an asynchronous API function for use in a Builder (Chain Commands)同步异步 API 函数以在 Builder 中使用(链命令)
【发布时间】:2020-09-02 22:34:40
【问题描述】:

我在同步执行异步代码时遇到问题。

这是 API 的函数,它将加载的元素作为参数传递给回调。

function loadElement(url, onLoadedCallback)

我有一个 Builder 类,它应该接收元素,然后在加载后更改其属性。

class Builder {
    constructor() {
        this.element = {};
    }

    load(url) {
        loadElement(url, (element) => {this.element = element});
        return this;
    }

    build() {
        return this.element;
    }
}

但是当我像这样使用 Builder 时,返回的元素仍然是一个空对象。

var element1 = new Builder().load('testUrl').build();
console.log(element1);

结果是 {} 我有点预料到,因为元素需要大约 3 秒才能加载,console.log(element1) 会立即运行...

我需要一种重新同步异步回调的方法,以确保我的构建器链一个接一个地执行,并且当我在构建器上调用 .build() 时,this.element 不等于空对象。

我的主要问题是我无法更改 API 的加载函数以返回一个 Promise,这将是最好的解决方案。

希望有人能帮我解决这个问题。

【问题讨论】:

    标签: javascript asynchronous promise callback


    【解决方案1】:

    不可能使异步任务变为同步。虽然您无法更改 load() 方法以返回一个承诺,但您可以让构建器为元素包装一个承诺并让 build() 返回一个承诺:

    class Builder {
        constructor() {
            this.elementPromise = Promise.resolve({});
        }
    
        load(url) {
            this.elementPromise = new Promise(resolve => {
                loadElement(url, resolve);
            });
            return this;
        }
    
        build() {
            return this.elementPromise;
        }
    }
    

    用法是

    const element1 = await new Builder().load('testUrl').build();
    //               ^^^^^
    console.log(element1);
    

    new Builder().load('testUrl').build().then(console.log);
    

    【讨论】:

    • 感谢您对我的帮助!我想过 Promises,但我从来没有想过将它用作构建器的包装器
    【解决方案2】:
    class Builder {
    constructor() {
        this.element = {};
    }
    
    load(url) {
        loadElement(url, (element) => {this.element = element;return this;});
        
    }
    
    build() {
        return this.element;
    }
    

    }

    将return语句移到loadElement的回调函数中

    【讨论】:

    • 这样会报错:cannot read property build of undefined... 这是因为load函数没有返回任何东西,所以默认返回undefined。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多