如何在Node.JS中一遍又一遍地并行下载多个url



我在家里有一个小型的物联网设置,需要反复查询少量RESTful api以从多个传感器获取数据。每个URL都需要在不同尝试之间使用自定义延迟进行查询。

在Node.JS中实现这个的最好方法是什么?最终目标是解析返回的JSON并在Realm DB中持久化。

我正试图实现这个承诺,并努力想出两件事:1)我应该把然后()处理服务器的响应(模拟setTimeout), 2)如何在超时后重新安排URL。

const conf = [
{
url: "http://google.com",
timeout: 2400, // ms between queries
},
{
url: "http://duckduckgo.com",
timeout: 2000,
}
];
let activePromises = [];
conf.forEach( function(el) {
activePromises.push( new Promise(
function webHandler(resolve, reject) {
console.log(`Starting request to ${ el.url }...`);
setTimeout( () => {
console.log(`Resolving ${ el.url } after ${ el.timeout }ms`);
resolve('body'); // real-world contents will be a JSON document
// how to repeat the same API query after el.timeout ms???
}, 30);
}
));
});

使用Promise.all()map()

const conf = [
{
url: "http://google.com",
timeout: 2400, // ms between queries
},
{
url: "http://duckduckgo.com",
timeout: 2000,
}
];
Promise.all(conf.map(async item=> await doTask(item.url,item.timeout)))
const doTask=(url,timeout)=>{
return new Promise((resolve, reject)=> {
..... 
}
}

如果你必须每n秒重复一次动作,你需要寻找setInterval

const conf = [
{
url: "http://google.com",
timeout: 2400, // ms between queries
},
{
url: "http://duckduckgo.com",
timeout: 2000,
}
];
const fetchResult = url => api(url) //pseudo code here
let results = Array(conf.length).fill(Promise.resolve(null))
conf.foreach(({url, timeout}, i) => {
setInterval(async() => {
const res =  await fetchResult(url)
results[i] = res;
}, timeout)
})

在结果数组中有n个承诺。
那么你可以使用Promise。如果你喜欢的话,可以把它们分开处理

假设(为了简单起见)loadData是将从URL获取数据的函数(您目前使用超时模拟)。

如果你想定期发送请求,你可以简单地使用setInterval:

conf.forEach(el => {
setInterval(() => {
loadData(el.url)
.then((body) => { /** Save to DB here */ });
.catch(() => { /** Handle error */ });
}, el.timeout);
});

但是如果你想等待loadData解析,然后等待超时时间,你可以这样做:

function process() {
loadData(el.url).then((body) => {
/** Save to DB here */
setTimeout(process, el.timeout);
}).catch(() => { /** Handle error */ });
}

,它将在指定的超时时间后调用相同的函数。

最新更新