Javascript React中循环的内部异步函数
我在React中有一段代码,它调用Dark Sky API并返回特定日期的天气数据。每个请求都有一个特定的日期。请求成功后,我通过setState将数据放入数组中。代码运行正常,但每个请求都是异步运行的,因此数据会按每个调用完成的顺序推送到数组中,因此不会给我一个有序的日期列表。代码如下:Javascript React中循环的内部异步函数,javascript,reactjs,async-await,Javascript,Reactjs,Async Await,我在React中有一段代码,它调用Dark Sky API并返回特定日期的天气数据。每个请求都有一个特定的日期。请求成功后,我通过setState将数据放入数组中。代码运行正常,但每个请求都是异步运行的,因此数据会按每个调用完成的顺序推送到数组中,因此不会给我一个有序的日期列表。代码如下: loadPreviousMonth = async () => { const current = {...this.state}; for (let i=30; i >= 1; i--
loadPreviousMonth = async () => {
const current = {...this.state};
for (let i=30; i >= 1; i--) {
const date = new Date();
const previousDay = Math.floor(date.setDate(date.getDate() - i) / 1000);
const url = `/api/darksky?latitude=${current.latitude}&longitude=${current.longitude},${previousDay}`;
await darkSky(url, this.onTimeRequestSuccess, this.onError);
}
}
谢谢 您可以使用。。其中将按顺序运行:
async function processArray(array) {
for (const item of array) {
await darkSky(url, this.onTimeRequestSuccess, this.onError);
}
console.log('Done!');
}
你可以用。。其中将按顺序运行:
async function processArray(array) {
for (const item of array) {
await darkSky(url, this.onTimeRequestSuccess, this.onError);
}
console.log('Done!');
}
您可以尝试递归函数调用。大概是这样的:
function darkSky(url, onTimeRequestSuccess, onError) {
return fecth(url).then(onTimeRequestSuccess).catch(onError);
}
var delay=ms=>newpromise(res=>setTimeout(res,ms));
函数执行器(迭代){
如果(迭代>0){
延迟(500)。然后(()=>{
console.log(迭代)
执行者(迭代-1)
})
}
}
ExecuteInoder(30)
您可以尝试递归函数调用。大概是这样的:
function darkSky(url, onTimeRequestSuccess, onError) {
return fecth(url).then(onTimeRequestSuccess).catch(onError);
}
var delay=ms=>newpromise(res=>setTimeout(res,ms));
函数执行器(迭代){
如果(迭代>0){
延迟(500)。然后(()=>{
console.log(迭代)
执行者(迭代-1)
})
}
}
ExecuteInoder(30)
使用。Waaay比在循环中使用递归或等待更快,因为所有API调用都将同时进行,而不是按顺序进行
const promises = [];
for (let i=30; i >= 1; i--) {
const date = new Date();
const previousDay = Math.floor(date.setDate(date.getDate() - i) / 1000);
const url = `/api/darksky?latitude=${current.latitude}&longitude=${current.longitude},${previousDay}`;
promises.push(darkSky(url, this.onTimeRequestSuccess, this.onError));
}
Promise.all(promises).then(arrOfResults => {
// setState here
});
使用。Waaay比在循环中使用递归或等待更快,因为所有API调用都将同时进行,而不是按顺序进行
const promises = [];
for (let i=30; i >= 1; i--) {
const date = new Date();
const previousDay = Math.floor(date.setDate(date.getDate() - i) / 1000);
const url = `/api/darksky?latitude=${current.latitude}&longitude=${current.longitude},${previousDay}`;
promises.push(darkSky(url, this.onTimeRequestSuccess, this.onError));
}
Promise.all(promises).then(arrOfResults => {
// setState here
});
问题在于,没有什么可以确保一个请求在另一个请求之前完成,但这取决于函数
darkSky
的实现方式。据我所知,从您的代码中可以猜到,它将如下所示:
function darkSky(url, onTimeRequestSuccess, onError) {
return fecth(url).then(onTimeRequestSuccess).catch(onError);
}
因为您正在使用onTimeRequestSuccess
作为对darkSky
内部承诺的解析,processArray
中的等待不会等待获取承诺,而是等待onTimeRequestSuccess
的结果。这就是为什么秩序得不到维持
如果您想保持顺序(在获取数据后不重新排序),并且不需要连续调用30次,一种方法是创建一个包含所有查询承诺的数组,使用Promise.all
等待所有查询都被解析,然后将整个数组设置为状态。例如:
loadPreviousMonth = () => {
const current = {...this.state};
const promises = [];
for (let i=30; i >= 1; i--) {
const date = new Date();
const previousDay = Math.floor(date.setDate(date.getDate() - i) / 1000);
const url = `/api/darksky?latitude=${current.latitude}&longitude=${current.longitude},${previousDay}`;
promises.push(fetch(url));
}
Promise.all(promises).then((results) => this.setState({results: results}));
}
问题在于,没有什么可以确保一个请求在另一个请求之前完成,但这取决于函数
darkSky
的实现方式。据我所知,从您的代码中可以猜到,它将如下所示:
function darkSky(url, onTimeRequestSuccess, onError) {
return fecth(url).then(onTimeRequestSuccess).catch(onError);
}
因为您正在使用onTimeRequestSuccess
作为对darkSky
内部承诺的解析,processArray
中的等待不会等待获取承诺,而是等待onTimeRequestSuccess
的结果。这就是为什么秩序得不到维持
如果您想保持顺序(在获取数据后不重新排序),并且不需要连续调用30次,一种方法是创建一个包含所有查询承诺的数组,使用Promise.all
等待所有查询都被解析,然后将整个数组设置为状态。例如:
loadPreviousMonth = () => {
const current = {...this.state};
const promises = [];
for (let i=30; i >= 1; i--) {
const date = new Date();
const previousDay = Math.floor(date.setDate(date.getDate() - i) / 1000);
const url = `/api/darksky?latitude=${current.latitude}&longitude=${current.longitude},${previousDay}`;
promises.push(fetch(url));
}
Promise.all(promises).then((results) => this.setState({results: results}));
}
您不应该无序地保存状态中的数据,并在从状态中检索数据之后但在显示给用户之前对其进行排序吗。订购30个项目的数组只需几毫秒。但是,只有在收到当前api调用后才进行下一次api调用将永远需要进行30次api调用。我可以这样做,但我希望我可以按顺序运行每个api调用,这样我就不必采取额外的步骤。你应该采取额外的步骤,编辑了我以前的评论,添加了“为什么”。谢谢,我最后只是将数组排序在:)之后。您不应该将数据无序保存在您的状态中,并在从状态检索后但在显示给用户之前对其排序吗。订购30个项目的数组只需几毫秒。但是,只有在收到当前api调用后才进行下一个api调用将永远需要30个api调用。我可以这样做,但我希望我可以按顺序运行每个api调用,这样我就不必采取额外的步骤。你应该采取额外的步骤,编辑我以前的注释以添加“为什么”。谢谢,我只是在以下位置对数组进行排序:)