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



tldr如何从Promise中设置类变量

我砰砰async/await

砰砰砰砰砰砰�当然有很多例子和博客文章,但它们then'结果只console.log,我不需要。

我的用例非常简单,我想使用 fetch 从 json 加载翻译(如果它们尚未加载(,然后使用函数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

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

第二次编辑

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

您需要等到翻译完成。最简单的方法是使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))

如果你想要,你也必须把你的翻译异步。 因此,您也需要在该函数上使用异步和等待。

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

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

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

而且,由于您也需要等待控制台.log并且由于await只能在异步函数中,因此您可以执行以下操作..

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

解释

函数translate返回this._loadTranslations()的结果,即Promise。然后,控制台.log语句等待该 Promise,并在实现后输出,也就是说,一旦您从 data.json 获得 JSON。

实例

化类、从 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(。

最新更新