javascript,async,await:无法将值提取到类变量中

问题描述 投票:1回答:4

tldr如何在Promise中设置类变量

我正在敲打我的头,因为我太傻了,不能使用async/await和javascript。当然有很多例子和博客文章,但它们是'then'inning结果只有console.log,我不需要。

我的用例非常简单,我想使用fetch从json加载翻译(如果尚未加载),然后使用函数translate返回翻译的值。

我想如果我使用then,那么执行暂停直到Promiseresolves或失败。

class Test {

    constructor() {
    }

    /**
     * Loads translations
     */
    async _loadTranslations() {
        console.log("Loading tanslations");
        let response = await fetch('data.json');
        let json =  await response.json();
        return json;
    };

    translate(key, language) {
      if(!this.translation){
         this._loadTranslations().then(data =>{
            console.log("data is loaded!", data);
            this.translation = data;});
       }
       return this.translations[language][key];
    }

}

console.log("translation",new Test().translate("MEGA_MENU_CMD","de-DE"))

但它总是记录translation undefined

我不想要类似的东西

  new Test()._loadTranslations().then(r => console.log("result",r))

因为我想在模板中使用翻译功能,我不想在我的所有模板中使用.then

编辑我不知道如何使用fetch从API获取数据并将其设置为类的模型。在我看来,thens和callbacks做了不同的事情。或者如何正确实例化类,从API加载数据然后使用这些数据?

第二次编辑:

实际上,我只想创建一个TranslationMixin并加载一次翻译。然后在我的页面中(我正在使用Polymer)我想使用return html '<div>${this.translate("de-De","propertyX"}<div>',这就是为什么我不想要Promise而只是简单的字符串。事实上,翻译应该在施工期间加载完成。但是当fetch返回Promise时,我被Promise困住并且未能获得价值(#sigh)。所以我可能只是坚持常规XMLHttpRequest ...

javascript async-await
4个回答
2
投票

您需要等到翻译完成。最简单的方法是使translate成为异步函数。这将返回一个承诺,您可以在then()中获得翻译:

class Test {

    constructor() {
    }

    /**
     * Loads translations
     */
    async _loadTranslations() {
        console.log("Loading tanslations");
        this.translation = "some translation"
        return this.translation;
    };

    async translate(key, language) {
      if(!this.translation){
         return this._loadTranslations().then(data =>{
            console.log("data is loaded!", data);
            return  data;});
       }
       return this.translation;
    }

}
new Test().translate("MEGA_MENU_CMD","de-DE")
.then(translate => console.log(translate))

0
投票

如果你想要,你必须把你的翻译异步。所以你需要在该函数上使用async和await。

因为他实际上会在_loadTranslations()中做你期望的事情并且他会等待结果,但是因为调用它的函数不是异步的,所以他会做所有事情直到最后!我希望这有帮助。


0
投票

这是您首先要寻找的异步/等待解决方案。

translate(key, language){
    return this.translation
    ? this.translation[language][key]
    : this._loadTranslations()
}

因为,你需要等待console.log,因为await只能在异步函数中,你可以执行以下操作。

(async()=>{
    console.log("translation", await new Test().translate("MEGA_MENU_CMD","de-DE"))
})()

说明

函数translate返回this._loadTranslations()的结果,即Promise。然后,console.log语句等待Promise并在完成后输出,即,一旦从data.json获得JSON。


0
投票

如何实例化一个类,从API加载数据然后使用这些数据?

在实例化类之前加载数据,然后实例可以同步使用它。

您应该在创建实例之前以静态方法加载翻译,这样您就不必在translate方法中等待它们:

class Test {
    constructor(t) {
        this.translations = t;
    }

    /**
     * Loads translations
     */
    static async fromLoadedTranslations() {
        console.log("Loading tanslations");
        let response = await fetch('data.json');
        let json = await response.json();
        console.log("data is loaded!", data);
        return new this(json);
    }

    translate(key, language) {
        return this.translations[language][key];
    }
}

Test.fromLoadedTranslations().then(test => {
    console.log("translation", test.translate("MEGA_MENU_CMD","de-DE"));
    // or pass `test` to your polymer template
});

(async function() {
    const test = await Test.fromLoadedTranslations();
    console.log("translation", test.translate("MEGA_MENU_CMD","de-DE"));
    // or pass `test` to your polymer template
}());

没有办法异步加载数据而不是等待(使用thenawait)某处。

© www.soinside.com 2019 - 2024. All rights reserved.