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

时间:2018-09-10 14:23:51

标签: javascript async-await

tldr 如何在None内设置类变量

我太笨了,以至于无法将Promise与JavaScript配合使用。当然有很多示例和博客文章,但是它们只是将结果async/await插入then'中,这是我不需要的。

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

我认为如果我使用translate,则执行会暂停,直到then解决或失败为止。

Promise

但是它总是记录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从API获取数据并将其设置为类的模型。我认为fetchthen做不同的事情。还是实例化类,从API加载数据然后使用该数据的正确方法是什么?

第二次修改

实际上,我只想创建一个TranslationMixin并加载一次翻译。然后在我的页面中(我正在与Polymer一起玩),我想使用callback,这就是为什么我不希望Promise而是只使用纯字符串的原因。实际上,应在构建和完成过程中加载翻译。但是当return html '<div>${this.translate("de-De","propertyX"}<div>'返回fetch时,我受Promise的束缚,无法获取值(#sigh)。所以大概我只坚持常规的Promise ...

4 个答案:

答案 0 :(得分: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))

答案 1 :(得分:0)

如果需要,还必须将转换异步。 因此,您还需要使用async并等待该函数。

因为他实际上将按照_loadTranslations()的要求进行操作,并且将等待结果,但是由于调用该函数的函数并不异步,因此他将尽一切努力直到最后! 我希望这有帮助。

答案 2 :(得分: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后输出。

答案 3 :(得分: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)。