ReactJS -> 从 promise 存储变量
ReactJS -> store variable from promise
我正在尝试弄清楚如何将 promise return 阶段存储到变量中。在此用例中,我使用 google 地图和 google 的地理编码器将 JSON 地址文件转换为经纬度对象数组以制作标记,但我不管怎样,我很好奇。这是通过一个单一的承诺完成的,但由于我被迫循环遍历数据并执行调用,我无法调用另一个函数并离开承诺,因为我最终必须重复承诺。这意味着我需要将对象存储在一个单独的变量中。请参阅下面的代码部分。
address.json
{
"address" : "Oosterpark 9",
"city" : "Amsterdam",
"name" : "Onze Lieve Vrouwe Gasthuis"
"zipcode" : "1091 AC"
},
{
"address" : "Jan Tooropstraat 164",
"city" : "Amsterdam",
"name" : "Sint Lucas Andreas Hospital"
"zipcode" : "1061 AE"
}
Map.js
makeMarker(a){
Geocode.setApiKey(this.apiKey);
let arr = [];
for(let i=0; i < a.length; i++){
let address = b[i].address.replace(" ","+") + ',+'+b[i].zipcode.replace(" ","+")+',+'+b[i].city;
arr[i] = Geocode.fromAddress(address).then(
response => {
const {lat, lng} = response.results[0].geometry.location;
console.log(lat, lng);
return {lat: lat, lng: lng};
}
);
}
return arr;
}
在这种情况下,在构造函数中调用上述函数,其中一个变量正在等待由 makeMarker 函数的结果定义。在这种情况下,当它应该 return [{lat: __, lng: __,}, {lat: __, lng: __,}] 时,它只会 returns [promise, promise] .
我希望听到您关于如何解决此用例的一些想法!
您可以使用 Promise.all,在 class
的实例上创建一个承诺数组,然后在 componentDidMount
(或其他有用的生命周期挂钩)运行 :
Promise.all(promies).then(...)
所以像这样:
makeMarker(a){
Geocode.setApiKey(this.apiKey);
let arr = [];
for(let i=0; i < a.length; i++){
let address = b[i].address.replace(" ","+") + ',+'+b[i].zipcode.replace(" ","+")+',+'+b[i].city;
arr[i] = Geocode.fromAddress(address)
}
this.promises = arr;
}
然后在您的代码的其他地方:
Promise.all(this.promises).then(
listOfResponses => {
// rest of your code
}
)
下面是 Promise.all
的这种用法的一个小例子
const data = [1, 2, 3, 4, 5, 6];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
fetchedData: []
}
this.promises = data.map(d => {
return new Promise((resolve) => {
setTimeout(() => resolve(d),1500);
})
});
}
componentDidMount() {
Promise.all(this.promises).then(fetchedData => this.setState({ fetchedData }));
}
render() {
const { fetchedData } = this.state;
return (
<div>
{fetchedData.length ? fetchedData.map(d => <div>{d}</div>) : "Loading..."}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
@Sagiv b.g 使用 Promise.all 的答案是最好的方法。
这是另一种方法。
var arr = [];
makeMarker(a){
Geocode.setApiKey(this.apiKey);
for(let i=0; i < a.length; i++){
let address = b[i].address.replace(" ","+") + ',+'+b[i].zipcode.replace(" ","+")+',+'+b[i].city;
Geocode.fromAddress(address).then(
response => {
const {lat, lng} = response.results[0].geometry.location;
console.log(lat, lng);
addToArr({lat: lat, lng: lng},b);
}
);
}
}
addToArr(latLongObj,b){
arr.push(latLongObj);
if(arr.length >= b.length){
//callYourfunction and do the logic
}
}
我正在尝试弄清楚如何将 promise return 阶段存储到变量中。在此用例中,我使用 google 地图和 google 的地理编码器将 JSON 地址文件转换为经纬度对象数组以制作标记,但我不管怎样,我很好奇。这是通过一个单一的承诺完成的,但由于我被迫循环遍历数据并执行调用,我无法调用另一个函数并离开承诺,因为我最终必须重复承诺。这意味着我需要将对象存储在一个单独的变量中。请参阅下面的代码部分。
address.json
{
"address" : "Oosterpark 9",
"city" : "Amsterdam",
"name" : "Onze Lieve Vrouwe Gasthuis"
"zipcode" : "1091 AC"
},
{
"address" : "Jan Tooropstraat 164",
"city" : "Amsterdam",
"name" : "Sint Lucas Andreas Hospital"
"zipcode" : "1061 AE"
}
Map.js
makeMarker(a){
Geocode.setApiKey(this.apiKey);
let arr = [];
for(let i=0; i < a.length; i++){
let address = b[i].address.replace(" ","+") + ',+'+b[i].zipcode.replace(" ","+")+',+'+b[i].city;
arr[i] = Geocode.fromAddress(address).then(
response => {
const {lat, lng} = response.results[0].geometry.location;
console.log(lat, lng);
return {lat: lat, lng: lng};
}
);
}
return arr;
}
在这种情况下,在构造函数中调用上述函数,其中一个变量正在等待由 makeMarker 函数的结果定义。在这种情况下,当它应该 return [{lat: __, lng: __,}, {lat: __, lng: __,}] 时,它只会 returns [promise, promise] .
我希望听到您关于如何解决此用例的一些想法!
您可以使用 Promise.all,在 class
的实例上创建一个承诺数组,然后在 componentDidMount
(或其他有用的生命周期挂钩)运行 :
Promise.all(promies).then(...)
所以像这样:
makeMarker(a){
Geocode.setApiKey(this.apiKey);
let arr = [];
for(let i=0; i < a.length; i++){
let address = b[i].address.replace(" ","+") + ',+'+b[i].zipcode.replace(" ","+")+',+'+b[i].city;
arr[i] = Geocode.fromAddress(address)
}
this.promises = arr;
}
然后在您的代码的其他地方:
Promise.all(this.promises).then(
listOfResponses => {
// rest of your code
}
)
下面是 Promise.all
const data = [1, 2, 3, 4, 5, 6];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
fetchedData: []
}
this.promises = data.map(d => {
return new Promise((resolve) => {
setTimeout(() => resolve(d),1500);
})
});
}
componentDidMount() {
Promise.all(this.promises).then(fetchedData => this.setState({ fetchedData }));
}
render() {
const { fetchedData } = this.state;
return (
<div>
{fetchedData.length ? fetchedData.map(d => <div>{d}</div>) : "Loading..."}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
@Sagiv b.g 使用 Promise.all 的答案是最好的方法。 这是另一种方法。
var arr = [];
makeMarker(a){
Geocode.setApiKey(this.apiKey);
for(let i=0; i < a.length; i++){
let address = b[i].address.replace(" ","+") + ',+'+b[i].zipcode.replace(" ","+")+',+'+b[i].city;
Geocode.fromAddress(address).then(
response => {
const {lat, lng} = response.results[0].geometry.location;
console.log(lat, lng);
addToArr({lat: lat, lng: lng},b);
}
);
}
}
addToArr(latLongObj,b){
arr.push(latLongObj);
if(arr.length >= b.length){
//callYourfunction and do the logic
}
}