观看 API 更新
Watch an API for Updates
我正在尝试为 https://api.exchangeratesapi.io/latest
制作一个 API 手表
并检测是否有任何变化,这样我就可以像网络挂钩通知一样更新我的客户。但是我正在做的是
while(true){
fetch(https://api.exchangeratesapi.io/latest)
.then(res => ......
}
我正在缓存结果,并一直检查是否有任何变化,如果有,我会向客户端发送请求。
我正在寻找一种 更好的 方法来提取数据而不是进行 while 循环
如果您使用 while
循环,您可能会在一个 returns 之前发送许多请求。甚至当一个 returns 时,它也不一定是有序的。这是一个简单的例子,说明如果出现网络峰值可能会发生什么,例如:
const sleep = ms => new Promise(res => setTimeout(res, ms));
async function mockNetworkCall(num) {
const timings = [50, 150, 50]
console.log(`sending request ${num}`);
await sleep(timings[num]);
console.log(`request ${num} finished`)
}
for(let i = 0; i < 3; i++) {
mockNetworkCall(i);
}
如果您改为采用仅在最后一个请求完成时执行新请求的方法,则可以避免 while
循环。在这种情况下,您在任何时候都只会激活一个请求,并且您知道您正在按顺序获得结果。
您可以将其逻辑包装在一个简单的函数中,以便在前一个请求完成时观看 URL 并且仅 re-initiate 一个请求。这是此类功能的框架 - 它可能需要根据您的需要进行调整:
function watch({ url, retryCount, lastResponse = null}) {
fetch(url)
.then(res => {
/* do something */
return res;
})
.then(res => watch({url, retryCount, lastResponse: res})) //launch again
.catch(err => {
/* handle error */
console.error("error getting URL", err);
console.warn("retries left: ", retryCount);
if (retryCount-- > 0) {
watch({url, retryCount, lastResponse});
}
})
}
watch({url: "google.com", retryCount: 3});
或使用 async/await
相同
async function watch({ url, retryCount, lastResponse = null}) {
try {
const res = await fetch(url);
/* do something */
watch({url, retryCount, lastResponse: res}); //launch again
} catch (err) {
/* handle error */
console.error("error getting URL", err);
console.warn("retries left: ", retryCount);
if (retryCount-- > 0) {
watch({url, retryCount, lastResponse});
}
}
}
watch({url: "google.com", retryCount: 3});
我正在尝试为 https://api.exchangeratesapi.io/latest
制作一个 API 手表
并检测是否有任何变化,这样我就可以像网络挂钩通知一样更新我的客户。但是我正在做的是
while(true){
fetch(https://api.exchangeratesapi.io/latest)
.then(res => ......
}
我正在缓存结果,并一直检查是否有任何变化,如果有,我会向客户端发送请求。
我正在寻找一种 更好的 方法来提取数据而不是进行 while 循环
如果您使用 while
循环,您可能会在一个 returns 之前发送许多请求。甚至当一个 returns 时,它也不一定是有序的。这是一个简单的例子,说明如果出现网络峰值可能会发生什么,例如:
const sleep = ms => new Promise(res => setTimeout(res, ms));
async function mockNetworkCall(num) {
const timings = [50, 150, 50]
console.log(`sending request ${num}`);
await sleep(timings[num]);
console.log(`request ${num} finished`)
}
for(let i = 0; i < 3; i++) {
mockNetworkCall(i);
}
如果您改为采用仅在最后一个请求完成时执行新请求的方法,则可以避免 while
循环。在这种情况下,您在任何时候都只会激活一个请求,并且您知道您正在按顺序获得结果。
您可以将其逻辑包装在一个简单的函数中,以便在前一个请求完成时观看 URL 并且仅 re-initiate 一个请求。这是此类功能的框架 - 它可能需要根据您的需要进行调整:
function watch({ url, retryCount, lastResponse = null}) {
fetch(url)
.then(res => {
/* do something */
return res;
})
.then(res => watch({url, retryCount, lastResponse: res})) //launch again
.catch(err => {
/* handle error */
console.error("error getting URL", err);
console.warn("retries left: ", retryCount);
if (retryCount-- > 0) {
watch({url, retryCount, lastResponse});
}
})
}
watch({url: "google.com", retryCount: 3});
或使用 async/await
async function watch({ url, retryCount, lastResponse = null}) {
try {
const res = await fetch(url);
/* do something */
watch({url, retryCount, lastResponse: res}); //launch again
} catch (err) {
/* handle error */
console.error("error getting URL", err);
console.warn("retries left: ", retryCount);
if (retryCount-- > 0) {
watch({url, retryCount, lastResponse});
}
}
}
watch({url: "google.com", retryCount: 3});