我打印了一个挂起的承诺。正如您所看到的,我从get请求回调中调用并打印findLocation,但返回的promise带有未定义的值。尝试对此进行调试时,findLocation返回的值为";位置[随机]";它是一个物体。找不到打印带有未定义的承诺的原因。我希望承诺的价值是";位置[随机]";这是一个有效的对象。
import express from "express";
import getCities from "./api/getCities.js";
import useOpenTripMap from "./api/useOpenTripMap.js";
const app = express();
app.use(express.json());
// gets an array of cities
const citiesArray = getCities();
const radius = 1000;
// locations results limit
const limit = 20;
const findLocation = async () => {
return citiesArray
.then((cities) => {
let random = Math.floor(Math.random() * cities.length);
useOpenTripMap("geoname", encodeURI("name=" + cities[random].name)).then(
(city) => {
useOpenTripMap(
"radius",
encodeURI(
`radius=${radius}&limit=${limit}&lon=${city.lon}&lat=${city.lat}&format=json`
)
).then((locations) => {
// if no location found try again with another city
if (!Array.isArray(locations) || !locations.length) {
return findLocation();
}
random = Math.floor(Math.random() * locations.length);
// console.log(locations[random]);
return locations[random]; //returns an object
});
}
);
})
.catch((error) => error);
};
app.get("/random", (req, res, next) => {
console.log(findLocation()); //a pending promise with undefined value
// .then((location) => {
// console.log(location);
// res.json(location);
// })
// .catch((error) => console.log(error));
});
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log("server is running on port", port);
});
您需要等待承诺。所以坚持使用then/catch版本(尽管我建议使用async/await(。
findLocation().then(value => console.log(value));
或异步/等待语法
app.get("/random", async (req, res, next) => {
const location = await findLocation();
console.log(location);
});
您可能想要退回任何useOpenTripMap
更新:尝试findLocation 的此实现
const findLocation = async () => {
try {
const cities = await citiesArray; // a promise?!
// better would be
const cities = await getCities();
let random = Math.floor(Math.random() * cities.length);
const city = await useOpenTripMap(
"geoname",
encodeURI("name=" + cities[random].name)
);
const locations = await useOpenTripMap(
"radius",
encodeURI(
`radius=${radius}&limit=${limit}&lon=${city.lon}&lat=${city.lat}&format=json`
)
);
if (!Array.isArray(locations) || !locations.length) {
return findLocation(); // recursive call with no parameter change?
}
random = Math.floor(Math.random() * locations.length);
// console.log(locations[random]);
return locations[random]; //returns an object
} catch (error) {
console.error(error);
}
};
您错过了then
表中的return
。这就是为什么promise(citiesArray
(返回undefined
的原因。为了更易于阅读和简化,请使用async/await
方法。
const findLocation = async () => {
return citiesArray
.then((cities) => {
let random = Math.floor(Math.random() * cities.length);
// here return missed 👇🏻
return useOpenTripMap("geoname", encodeURI("name=" + cities[random].name)).then(
(city) => {
// here too 👇🏻
return useOpenTripMap(
"radius",
encodeURI(
`radius=${radius}&limit=${limit}&lon=${city.lon}&lat=${city.lat}&format=json`
)
).then((locations) => {
// if no location found try again with another city
if (!Array.isArray(locations) || !locations.length) {
return findLocation();
}
random = Math.floor(Math.random() * locations.length);
// console.log(locations[random]);
return locations[random]; //returns an object
});
}
);
})
.catch((error) => error);
};
异步/等待方法
const findLocation = async () => {
try {
const cities = await citiesArray()
let random = Math.floor(Math.random() * cities.length);
const city = await useOpenTripMap("geoname", encodeURI("name=" + cities[random].name))
const locations = await useOpenTripMap(
"radius",
encodeURI(
`radius=${radius}&limit=${limit}&lon=${city.lon}&lat=${city.lat}&format=json`
)
)
// if no location found try again with another city
if (!Array.isArray(locations) || !locations.length) {
return findLocation();
}
random = Math.floor(Math.random() * locations.length);
// console.log(locations[random]);
return locations[random]; //returns an object
} catch(err) {
console.log(err)
}
};