每当收到的响应具有async/await
时,我就会向length === 0
进行递归请求。问题是,当某些请求返回所需的数据时,promise的resolve(data);
部分似乎不起作用。
因此,在我的代码中,我已经到达进行多次递归调用的地步,最后收到的响应长度不为0。
注意:如果要测试代码,Github中发布了许多API密钥。
var apiKey = "yourApiKey";
var url = "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=";
function requestData(url) {
return fetch(url).then(response => {
if(response.ok) {
return response.json().then(data => {
return Promise.resolve(data);
});
} else {
return Promise.reject(response.status);
}
});
}
function NasaRequest(sun, limit, frecuency) {
return new Promise(async (resolve, reject) => {
var data = await requestData(url + sun + "&api_key=" + apiKey);
if(data.photos.length === 0 && !limit) {
setTimeout(async () => {
console.log("Delay for next request (sun " + sun + "): ", frecuency);
return await NasaRequest(sun - 1, limit, frecuency);
}, frecuency);
} else {
console.log("Resolve data:", data); // Code acutally reaches this point
resolve(data); // But this doesn't seem to work
}
});
};
async function init() {
try {
const currentValue = await NasaRequest(2175, false, 2000);
console.log("currentValue:", currentValue); // I want to reach this point, but is like the promise never returns
}catch(err){
console.error(err);
}
}
init();
那一刻,我想返回init()
调用函数的响应中的数据。但这似乎不起作用。
我在做什么错了?
答案 0 :(得分:2)
问题出在setTimeout
上。调用setTimeout
时,它将立即返回,并隐式返回undefined
。子序列返回在这一点上无关紧要。如果您只想暂停一下,然后继续尝试类似的事情
async function requestData(url) {
var response = await fetch(url);
if (response.ok) {
return response.json()
} else {
throw new Error(response.status);
}
}
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function nasaRequest(sun, limit, freq) {
var data = await requestData(url + sun + "&api_key=" + apiKey);
if (data.photos.length === 0 && !limit) {
await sleep(freq);
console.log("Delay for next request (sun " + sun + "): ", freq);
return await nasaRequest(sun - 1, limit, freq);
} else {
console.log("Resolve data:", data);
return data;
}
};
async function init() {
try {
const currentValue = await nasaRequest(2175, false, 2000);
console.log("currentValue:", currentValue);
} catch (err) {
console.error(err);
}
}
init();
我添加了一个简单的sleep
函数来处理暂停。我还修改了requestData
(删除了then
和Promise
部分)。
请注意,使用这种递归方法可能会遇到堆栈溢出。为避免该问题,您可以简单地使用循环并检查您的limit
变量。