需要通过代码的执行才能在Javascript中得到输出
Need to pass the execution of code to get output in Javascript
我在 React 应用程序中为 translation
使用以下代码。它的遗留应用程序。所以它们都是 class
组件和旧库。
import i18next from 'i18next';
import React from 'react';
import TransFile from './TransFile.js';
const LanguageDetector = require('i18next-browser-languagedetector');
const initReactI18next = require('react-i18next');
var output;
//API call
apiDelegate.getTranslations().then((result) => {
output = JSON.stringify(result);
alert("output1 =>"+result);
});
alert("output2 is:"+output);
i18next
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
en: output, //Here I need to assign output
},
fallbackLng: 'fr',
});
i18next.changeLanguage(navigator.language);
alert("Output3 is:"+output);
export default i18next;
它正在打印 output2
的警报,然后是 output3
,然后是 output1
。 output2
和 output1
是 undefined
。我需要按顺序打印它们,因为我需要在我的应用程序中使用 API
数据。它没有分配给实际变量
基本上我需要将 output
分配给我的 en
变量。代码行下方
en: output,
我不能使用 async await
因为 babel
不是 supporting
并且它是相当旧的应用程序所以当我更新 webpack 时失败。
apiDelegate
代码。
getTranslations() {
var token = sessionStorage.getItem('jwt');
if (token == null) {
token = '';
}
return new Promise((resolve) => {
request
.get(baseUrl.api + '/file_download/en') //API call
.set({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + token,
})
.then((value) => {
var result;
if (value.status === 200) {
result = value.body;
// alert(JSON.stringify(result));
}
resolve(result);
return result;
})
.catch((error) => {
var result;
if (error.status === 401 || error.status === 403) {
result = { status: -2, message: error, data: [] };
}
resolve(result);
});
});
}
可以使用 callback
或 setTimeOut
来完成吗?我知道它的基本知识,但我是初学者。无法解决同样的问题。请帮忙
编辑1:-
数据将存储在文件中,否则 API 输出将如下所示。
translation: {
app_header:"My contact",
app_address:"my address",
app_phone:"+1 93244 3223",
app_email:"abc@abc.com"
}
我在我的文件中使用 i18,如下所示。
import i18n from '../../../i18'
在组件中它将像下面这样使用
i18n.t("app_header")
因此 app_header
的值将在应用程序中被替换。
因为你有apiDelegate fn的依赖,你需要在调用API之后初始化i18next。然后只有你可以访问输出变量结果。
import i18next from 'i18next';
import React from 'react';
import TransFile from './TransFile.js';
const LanguageDetector = require('i18next-browser-languagedetector');
const initReactI18next = require('react-i18next');
//API call
apiDelegate.getTranslations().then((result) => {
var output;
output = JSON.stringify(result);
alert("output1 =>"+result);
//Moved the assigning logic here
i18next
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
en: output, //Here I need to assign output
},
fallbackLng: 'fr',
});
console.log('Output set to en', output)
i18next.changeLanguage(navigator.language);
});
export default i18next;
如需详细解答,请在此处附上示例反应代码,
- 我收到来自 API/FN 的翻译回复,将在 5 秒后 return
- 获得响应后,使用 API 结果
初始化 i18next
无需导出 i18next ,获取结果后在您的主应用程序中调用它即可。
import React, { useState } from "react";
import i18next from 'i18next';
function App(){
const [result,setResult] = useState('')
getTranslationFromAPi().then( response => {
i18next
.init({
resources: {
en: response, //Here I need to assign output
},
fallbackLng: 'fr',
});
i18next.changeLanguage(navigator.language);
})
//Mock funtion gives response after 5sec
function getTranslationFromAPi(){
return new Promise((resolve, rej)=>{
setTimeout(() => {
resolve({translation:{ln:'sample lang'}});
}, 5000);
})
}
setTimeout(() => {
setResult(i18next.t('ln'))
}, 10000);
return(
<div>
{/* Result will come after 10 sec */}
{result}
</div>
)
}
export default App;
我发现您的代码有几个问题。最重要的是,正如评论中提到的,您始终必须确保保持承诺链的运行。在 apiDelegate 中,您不必 return 一个新的承诺,只需 return 现有的请求。无论如何,请求已被弃用。此外,您所有的进口商品都有些混乱。在您的组件中,您必须确保只调用 i18 的 init 一次。我使用 useEffect 来实现它。
我试图用一个假的 api 为您制作一个 sample application 用于演示目的,以便您调试代码。您可以简单地注释掉 apiDelegate 中的行以使用 fetch 方法调用您真正的 api.
App.js
import i18n, { t } from "i18next";
import React, { useEffect, useState } from "react";
import { getTranslations } from "./apiDelegate";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
export default function App() {
const [init, setInit] = useState(false);
//API call
useEffect(() => {
(function () {
getTranslations().then((result) => {
alert("output1 =>" + result);
i18n
.use(initReactI18next)
.use(LanguageDetector)
.init({
resources: {
en: (alert("output2 =>" + JSON.stringify(result)), result) //Here I need to assign output
},
fallbackLng: "fr"
})
.then(() => {
//i18n.changeLanguage(navigator.language);
i18n.changeLanguage("en");
setInit(true);
});
});
})();
}, []);
return (
<div i18nready={init.toString()} className="App">
<div>{t("app_header")}</div>
</div>
);
}
apiDelegate.js
//import request from "request"; deprecated
export const getTranslations = () => {
var token = sessionStorage.getItem("jwt");
if (token == null) {
token = "";
}
// return fetch(baseUrl.api + '/file_download/en', { //when using api
return fetch(
//remove line when using api
"./translation.json" //remove line when using api
/* , { //when using api
method: 'post',
headers: new Headers({
'Authorization': "Bearer " + token,
"Content-Type": "application/json",
Accept: "application/json"
}),
body: 'A=1&B=2'
} */
)
.then((res) => res.json())
.then((result) => {
/* if (result.status === 200) { //when using api
return result.body;
} */
if (Object.entries(result).length) return result; //remove line when using api
return { status: -2, message: result.status, data: [] };
})
.catch((error) => {
return { status: -2, message: error.message, data: [] };
});
};
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import backend from 'i18next-http-backend';
import api from "../api";
var lang=navigator.language;
let loadResources= apiDelegate.getTranslations(lang);
const backendOptions = {
loadPath: 'http://localhost:8080/code/'+lang,
request: (options, url, payload, callback) => {
try {
loadResources.then((result) => {
callback(null, {
data: result,
status: 200,
});
});
} catch (e) {
console.error(e);
callback(null, {
status: 500,
});
}
},
};
i18n
.use(LanguageDetector)
.use(backend)
.init({
backend: backendOptions,
fallbackLng: "fr",
debug: false,
load:"languageOnly",
ns: ["translations"],
defaultNS: "translations",
keySeparator: false,
interpolation: {
escapeValue: false,
formatSeparator: ","
},
react: {
wait: true
}
});
i18n.changeLanguage(navigator.language);
export default i18n;
我在 React 应用程序中为 translation
使用以下代码。它的遗留应用程序。所以它们都是 class
组件和旧库。
import i18next from 'i18next';
import React from 'react';
import TransFile from './TransFile.js';
const LanguageDetector = require('i18next-browser-languagedetector');
const initReactI18next = require('react-i18next');
var output;
//API call
apiDelegate.getTranslations().then((result) => {
output = JSON.stringify(result);
alert("output1 =>"+result);
});
alert("output2 is:"+output);
i18next
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
en: output, //Here I need to assign output
},
fallbackLng: 'fr',
});
i18next.changeLanguage(navigator.language);
alert("Output3 is:"+output);
export default i18next;
它正在打印 output2
的警报,然后是 output3
,然后是 output1
。 output2
和 output1
是 undefined
。我需要按顺序打印它们,因为我需要在我的应用程序中使用 API
数据。它没有分配给实际变量
基本上我需要将 output
分配给我的 en
变量。代码行下方
en: output,
我不能使用 async await
因为 babel
不是 supporting
并且它是相当旧的应用程序所以当我更新 webpack 时失败。
apiDelegate
代码。
getTranslations() {
var token = sessionStorage.getItem('jwt');
if (token == null) {
token = '';
}
return new Promise((resolve) => {
request
.get(baseUrl.api + '/file_download/en') //API call
.set({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + token,
})
.then((value) => {
var result;
if (value.status === 200) {
result = value.body;
// alert(JSON.stringify(result));
}
resolve(result);
return result;
})
.catch((error) => {
var result;
if (error.status === 401 || error.status === 403) {
result = { status: -2, message: error, data: [] };
}
resolve(result);
});
});
}
可以使用 callback
或 setTimeOut
来完成吗?我知道它的基本知识,但我是初学者。无法解决同样的问题。请帮忙
编辑1:- 数据将存储在文件中,否则 API 输出将如下所示。
translation: {
app_header:"My contact",
app_address:"my address",
app_phone:"+1 93244 3223",
app_email:"abc@abc.com"
}
我在我的文件中使用 i18,如下所示。
import i18n from '../../../i18'
在组件中它将像下面这样使用
i18n.t("app_header")
因此 app_header
的值将在应用程序中被替换。
因为你有apiDelegate fn的依赖,你需要在调用API之后初始化i18next。然后只有你可以访问输出变量结果。
import i18next from 'i18next';
import React from 'react';
import TransFile from './TransFile.js';
const LanguageDetector = require('i18next-browser-languagedetector');
const initReactI18next = require('react-i18next');
//API call
apiDelegate.getTranslations().then((result) => {
var output;
output = JSON.stringify(result);
alert("output1 =>"+result);
//Moved the assigning logic here
i18next
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
en: output, //Here I need to assign output
},
fallbackLng: 'fr',
});
console.log('Output set to en', output)
i18next.changeLanguage(navigator.language);
});
export default i18next;
如需详细解答,请在此处附上示例反应代码,
- 我收到来自 API/FN 的翻译回复,将在 5 秒后 return
- 获得响应后,使用 API 结果 初始化 i18next
无需导出 i18next ,获取结果后在您的主应用程序中调用它即可。
import React, { useState } from "react";
import i18next from 'i18next';
function App(){
const [result,setResult] = useState('')
getTranslationFromAPi().then( response => {
i18next
.init({
resources: {
en: response, //Here I need to assign output
},
fallbackLng: 'fr',
});
i18next.changeLanguage(navigator.language);
})
//Mock funtion gives response after 5sec
function getTranslationFromAPi(){
return new Promise((resolve, rej)=>{
setTimeout(() => {
resolve({translation:{ln:'sample lang'}});
}, 5000);
})
}
setTimeout(() => {
setResult(i18next.t('ln'))
}, 10000);
return(
<div>
{/* Result will come after 10 sec */}
{result}
</div>
)
}
export default App;
我发现您的代码有几个问题。最重要的是,正如评论中提到的,您始终必须确保保持承诺链的运行。在 apiDelegate 中,您不必 return 一个新的承诺,只需 return 现有的请求。无论如何,请求已被弃用。此外,您所有的进口商品都有些混乱。在您的组件中,您必须确保只调用 i18 的 init 一次。我使用 useEffect 来实现它。 我试图用一个假的 api 为您制作一个 sample application 用于演示目的,以便您调试代码。您可以简单地注释掉 apiDelegate 中的行以使用 fetch 方法调用您真正的 api.
App.js
import i18n, { t } from "i18next";
import React, { useEffect, useState } from "react";
import { getTranslations } from "./apiDelegate";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
export default function App() {
const [init, setInit] = useState(false);
//API call
useEffect(() => {
(function () {
getTranslations().then((result) => {
alert("output1 =>" + result);
i18n
.use(initReactI18next)
.use(LanguageDetector)
.init({
resources: {
en: (alert("output2 =>" + JSON.stringify(result)), result) //Here I need to assign output
},
fallbackLng: "fr"
})
.then(() => {
//i18n.changeLanguage(navigator.language);
i18n.changeLanguage("en");
setInit(true);
});
});
})();
}, []);
return (
<div i18nready={init.toString()} className="App">
<div>{t("app_header")}</div>
</div>
);
}
apiDelegate.js
//import request from "request"; deprecated
export const getTranslations = () => {
var token = sessionStorage.getItem("jwt");
if (token == null) {
token = "";
}
// return fetch(baseUrl.api + '/file_download/en', { //when using api
return fetch(
//remove line when using api
"./translation.json" //remove line when using api
/* , { //when using api
method: 'post',
headers: new Headers({
'Authorization': "Bearer " + token,
"Content-Type": "application/json",
Accept: "application/json"
}),
body: 'A=1&B=2'
} */
)
.then((res) => res.json())
.then((result) => {
/* if (result.status === 200) { //when using api
return result.body;
} */
if (Object.entries(result).length) return result; //remove line when using api
return { status: -2, message: result.status, data: [] };
})
.catch((error) => {
return { status: -2, message: error.message, data: [] };
});
};
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import backend from 'i18next-http-backend';
import api from "../api";
var lang=navigator.language;
let loadResources= apiDelegate.getTranslations(lang);
const backendOptions = {
loadPath: 'http://localhost:8080/code/'+lang,
request: (options, url, payload, callback) => {
try {
loadResources.then((result) => {
callback(null, {
data: result,
status: 200,
});
});
} catch (e) {
console.error(e);
callback(null, {
status: 500,
});
}
},
};
i18n
.use(LanguageDetector)
.use(backend)
.init({
backend: backendOptions,
fallbackLng: "fr",
debug: false,
load:"languageOnly",
ns: ["translations"],
defaultNS: "translations",
keySeparator: false,
interpolation: {
escapeValue: false,
formatSeparator: ","
},
react: {
wait: true
}
});
i18n.changeLanguage(navigator.language);
export default i18n;