我有900多个URL列表,我想获取它们以进行日常cron作业,并且我正在使用Express.js。我在网上检查了一种方法和ran across this 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
...
我想要的结果是它等待一项内容的获取完成,然后再获取另一项内容。
答案 0 :(得分:1)
似乎过于复杂。
Id将其重写以遍历数组,并基于task
在异步/等待中进行提取或等待
//
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) {}
}
}
})()
答案 1 :(得分:0)
handleTask = async function(task) {
if (task.task === 'fetch') {
// make API call here
return APICALL(task.url)
} else if (task.task === 'wait') {
// sleep here
await sleep(task.duration)
}
}
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 },
...
]
await Promise.each(arrayOfAsyncTasks, async(task) => {
return handleTask(task)
})