javascript - 如何迭代 URL 数组并在移动到下一步之前等待响应
问题描述
我有一个包含 900 多个 url 的列表,我想为每天的 cron 作业获取这些 url,并且我正在使用 Express.js。我在网上查了一种方法来做到这一点,并遇到了这个 jsinclair page,所以我尝试实现它,但到目前为止还没有奏效。假设这是我的清单:
let arrayOfAsyncTasks = [
{task: 'fetch', url: 'http://thatapi.com/api1/thing'},
{task: 'wait', duration: 60000 },
{task: 'fetch', url: 'http://thatapi.com/api2/thing'},
{task: 'wait', duration: 60000 },
...
]
我试图做的是Array.reduce
在开始获取下一个 url 之前强制迭代坚持 60 秒的延迟,如下所示:
const starterPromise = Promise.resolve(null);
const log = result => console.log(result);
arrayOfAsyncTasks.reduce(
(p, spec) => p.then(() => {
runTask(spec)
.then(result => {
console.log(`Inside reduce function after runTask! result: `, result)
log(result)
})
})
.catch(err => console.log(`err: `, err) ),
starterPromise
);
以下是辅助函数:
function asyncTimeout(delay) {
console.log(`inside asyncTimeout! delay: `, delay);
return (new Promise(resolve => {setTimeout(() => resolve(delay), delay)}))
.then(d => `Waited ${d} seconds`);
}
function asyncFetch(url) {
console.log(`inside asyncFetch! url: `, url);
scrapeEbayCategory(url)
.then(response => (response.json()))
.then(text => `Fetched ${url}, and got back ${text}` );
}
function runTask(spec) {
return (spec.task === 'wait')
? asyncTimeout(spec.duration)
: asyncFetch(spec.url);
}
结果是它移动得太快了到下一个项目,然后在控制台中显示了多个延迟完成的控制台日志:
Waited 60000 seconds
Inside reduce function after runTask! result: Waited 60000 seconds
Waited 60000 seconds
Inside reduce function after runTask! result: Waited 60000 seconds
Waited 60000 seconds
Inside reduce function after runTask! result: Waited 60000 seconds
Waited 60000 seconds
Inside reduce function after runTask! result: Waited 60000 seconds
Waited 60000 seconds
Inside reduce function after runTask! result: Waited 60000 seconds
Waited 60000 seconds
Inside reduce function after runTask! result: Waited 60000 seconds
Waited 60000 seconds
Inside reduce function after runTask! result: Waited 60000 seconds
Waited 60000 seconds
Inside reduce function after runTask! result: Waited 60000 seconds
...
我想要的结果是它等待一个项目的获取完成,然后再移动以获取下一个项目。
解决方案
似乎过于复杂。
Id 重写它以循环遍历数组并基于task
,在 async/await 中进行获取或等待
//
const sleep = ms => new Promise(r => setTimeout(r, ms));
let arrayOfAsyncTasks = [{
task: 'fetch',
url: 'http://thatapi.com/api1/thing'
},
{
task: 'wait',
duration: 60000
},
{
task: 'fetch',
url: 'http://thatapi.com/api2/thing'
},
{
task: 'wait',
duration: 60000
}
]
;(async() => {
for (let task of arrayOfAsyncTasks) {
console.log('running', task)
if (task.task === 'wait') {
await sleep(task.duration)
}
if (task.task === 'fetch') {
try {
// await fetch(task.url)....
} catch (e) {}
}
}
})()
推荐阅读
- python - Plotly 表达 choropleth 箱
- javascript - 嵌套在填充中的过滤器
- reactjs - 如何根据交替模式有条件地渲染?
- java - @ApplicationPath 中的多个资源 URL
- python - 如何将列表中的每个元素乘以其在列表 python 中的位置
- excel - Excel If 函数没有空行
- c - CaptureStackBackTrace 和 SymGetLineFromAddr64 无法获取线路信息返回错误代码 487
- caching - 如何停止在 wordpress litespeed 中缓存部分页面?
- swiftui - 将修改器应用于 VStack 内部视图
- r - 需要帮助计算具有多个条件(包括部分字符串)的多列的出现次数,然后汇总这些结果