分步从数据库中获取项目并按顺序执行操作
fetch items from database in steps and perform operations sequentially
我有一个包含很多项目的数据库,我需要对每个项目执行一个操作 items.Unfortunatly,我必须按顺序 运行 这些操作并延迟每个操作以避免速率限制。
我的方法不会等待前面的操作完成,我最终会受到速率限制。我必须更改什么才能使其按顺序 运行?
setInterval(async () => {
await this.processQueue();
}, 1500)
private async processQueue() {
try {
//Only 3 requests per second allowed by the API so I only take 3 items from the database on every call
const bids = await getRepository(Bid).find({ order: { created_at: "ASC" }, take: 3, skip: 0 })
if (bids) {
for (const bid of bids) {
//check if active order exists
const activeOrder = await this.accountService.hasActiveOrder(bid.tokenId, bid.tokenAddress, 0);
if (!activeOrder) {
//perform async functions with that db item
const startTime = Date.now();
await this.placeBid(bid);
//delete from database so the next call to processQueue does not return the same itemsagain
await getRepository(Bid).delete({ id: bid.id })
const endTime = Date.now() - startTime;
}
}
}
} catch (error) {
console.error("TradingService processQeueu", error.message);
}
}
您的间隔计时器与 processQueue
函数正在完成的工作之间没有协调。将 async
函数作为其回调传递给 setInterval
具有误导性且无用; setInterval
不使用回调的 return 值,因此它 return 的承诺不用于任何事情。
相反,最小的改变是使用做等待processQueue
完成的东西,也许是一系列setTimeout
回调:
function processAndWait() {
processQueue().then(() => setTimeout(processAndWait, 1500));
// (Normally I'd have a `catch` call as well, but `processQueue`
// ensures it never rejects its promise)
}
请注意,队列处理完毕后等待 1500 毫秒。如果 API 允许每秒最多调用 3 次,那可能有点矫枉过正了。您可能 trim 到 1000 毫秒。
或者如果这是 class 中的方法(public 或私有):
processAndWait() {
processQueue().then(() => {
this.queueTimer = setTimeout(() => this.processAndWait(), 1500);
});
// (Normally I'd have a `catch` call as well, but `processQueue`
// ensures it never rejects its promise)
}
请注意,我添加了一些将计时器句柄保存到 属性 的内容,因此您可以使用 clearTimeout(this.queueTimer)
来停止进程。
我有一个包含很多项目的数据库,我需要对每个项目执行一个操作 items.Unfortunatly,我必须按顺序 运行 这些操作并延迟每个操作以避免速率限制。
我的方法不会等待前面的操作完成,我最终会受到速率限制。我必须更改什么才能使其按顺序 运行?
setInterval(async () => {
await this.processQueue();
}, 1500)
private async processQueue() {
try {
//Only 3 requests per second allowed by the API so I only take 3 items from the database on every call
const bids = await getRepository(Bid).find({ order: { created_at: "ASC" }, take: 3, skip: 0 })
if (bids) {
for (const bid of bids) {
//check if active order exists
const activeOrder = await this.accountService.hasActiveOrder(bid.tokenId, bid.tokenAddress, 0);
if (!activeOrder) {
//perform async functions with that db item
const startTime = Date.now();
await this.placeBid(bid);
//delete from database so the next call to processQueue does not return the same itemsagain
await getRepository(Bid).delete({ id: bid.id })
const endTime = Date.now() - startTime;
}
}
}
} catch (error) {
console.error("TradingService processQeueu", error.message);
}
}
您的间隔计时器与 processQueue
函数正在完成的工作之间没有协调。将 async
函数作为其回调传递给 setInterval
具有误导性且无用; setInterval
不使用回调的 return 值,因此它 return 的承诺不用于任何事情。
相反,最小的改变是使用做等待processQueue
完成的东西,也许是一系列setTimeout
回调:
function processAndWait() {
processQueue().then(() => setTimeout(processAndWait, 1500));
// (Normally I'd have a `catch` call as well, but `processQueue`
// ensures it never rejects its promise)
}
请注意,队列处理完毕后等待 1500 毫秒。如果 API 允许每秒最多调用 3 次,那可能有点矫枉过正了。您可能 trim 到 1000 毫秒。
或者如果这是 class 中的方法(public 或私有):
processAndWait() {
processQueue().then(() => {
this.queueTimer = setTimeout(() => this.processAndWait(), 1500);
});
// (Normally I'd have a `catch` call as well, but `processQueue`
// ensures it never rejects its promise)
}
请注意,我添加了一些将计时器句柄保存到 属性 的内容,因此您可以使用 clearTimeout(this.queueTimer)
来停止进程。