我正在开发一个应用程序,我需要根据用户的地理位置显示货币。如果失败,我想使用函数getCountryInfoByLanguage中的数据。
基本上,这段代码会运行它,但不等待if语句完成,使用它从函数中获得的货币,然后if语句完成并打印我要使用的countryCode。我有哪些可用选项?我尝试使用async / await,但是得到“对象不是有效的React子对象(找到:[object Promise])。如果要渲染子对象的集合,请改用数组。”
import convertPrice from "./convertPrice";
import getCountryInfoByLanguage from "./getCountryInfoByLanguage";
import axios from "axios";
export default (language, price) => {
const { countryCode, currency } = getCountryInfoByLanguage(language);
let countryCode_;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
axios
.get(
`http://api.geonames.org/countryCodeJSON?lat=${
position.coords.latitude
}&lng=${position.coords.longitude}&username=...`
)
.then(response => {
countryCode_ = response.data.countryCode;
console.log(countryCode_);
});
});
} else {
countryCode_ = countryCode;
}
console.log(countryCode_);
const convertedPrice = Math.round(convertPrice(price, currency) * 10) / 10;
const formattedPrice = convertedPrice.toLocaleString(countryCode_, {
style: "currency",
currency: currency
});
console.log(formattedPrice);
return formattedPrice;
};
解决此问题的多种方法。我已经写了一个使用React Hooks的简单示例。同样可以在ES6类组件中完成。诀窍是使React生命周期函数本身保持同步,但进行如下的asyc调用:
import React from "react";
import getCountryInfoByLanguage from "./getCountryInfoByLanguage";
import axios from "axios";
function Comp({ language }) {
const [countryCode, setCountryCode] = React.useState(null);
React.useEffect(() => {
(async function() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
axios
.get(
`http://api.geonames.org/countryCodeJSON?lat=${position.coords.latitude}&lng=${position.coords.longitude}&username=...`
)
.then(response => {
setCountryCode(response.data.countryCode);
});
});
} else {
const countryInfo = getCountryInfoByLanguage(language);
setCountryCode(countryInfo.countryCode);
}
})();
}, []);
return <div>Your country code : {countryCode}</div>;
}
如果{} else {}逻辑,您可以更改尝试{}抓住{}逻辑
try {
navigator.geolocation.getCurrentPosition(position => {
axios
.get(
`http://api.geonames.org/countryCodeJSON?lat=${
position.coords.latitude
}&lng=${position.coords.longitude}&username=...`
)
.then(response => {
countryCode_ = response.data.countryCode;
console.log(countryCode_);
});
});
}
catch(e) {
countryCode_ = countryCode;
}
第一个问题是此函数无法正确返回承诺。与其设置变量countryCode_而不是对其进行修改,而是要使用最终值进行解析。您几乎根本不需要“ countryCode_”。那里的问题是,您必须在if / else中计算两种情况的formattedPrice。这是我的处理方式:
import convertPrice from "./convertPrice";
import getCountryInfoByLanguage from "./getCountryInfoByLanguage";
import axios from "axios";
export default (language, price) => {
const { countryCode, currency } = getCountryInfoByLanguage(language);
return new Promise((resolve, reject) => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
axios
.get(
`http://api.geonames.org/countryCodeJSON?lat=${
position.coords.latitude
}&lng=${position.coords.longitude}&username=...`
)
.then(response => {
// assuming this response always exists
const geoCountryCode = response.data.countryCode;
console.log("countryCode from geolocation:", geoCountryCode);
resolve(getFormattedPrice(geoCountryCode));
});
});
} else {
console.log("default countryCode:", countryCode);
resolve(getFormattedPrice(countryCode));
}
});
};
function getFormattedPrice(countryCode) {
const convertedPrice = Math.round(convertPrice(price, currency) * 10) / 10;
const formattedPrice = convertedPrice.toLocaleString(countryCode, {
style: "currency",
currency: currency
});
console.log("formattedPrice:", formattedPrice);
return formattedPrice;
}
[使用它时,它仍将是异步的,因此无论调用它本身还是需要异步的,因此您可以使用await
,也可以使用.then(()=> {})来作为它的承诺。 。