Javascript 我如何才能确保一份工作不会';不要在公牛中跑两次?
我有两个函数,Javascript 我如何才能确保一份工作不会';不要在公牛中跑两次?,javascript,node.js,bull.js,Javascript,Node.js,Bull.js,我有两个函数,scheduleScan()和scan() scan()。但有一个问题,有些作业会运行两次 我想确保在任何给定时间只处理一个作业。我怎样才能做到这一点?我相信它与done(),(它在scan()中,现在被删除)有关,但我无法想出解决方案 牛版:3.12.1 重要的后期编辑:scan()调用另一个函数,它们可能调用也可能不调用其他函数,但它们都是同步函数,因此它们只在自己的作业完成时调用函数,前进的路只有一条。在“树”的末尾,我调用它,最后一个函数调用scheduleScan(),但
scheduleScan()
和scan()
scan()。但有一个问题,有些作业会运行两次
我想确保在任何给定时间只处理一个作业。我怎样才能做到这一点?我相信它与done()
,(它在scan()中,现在被删除)有关,但我无法想出解决方案
牛版:3.12.1
重要的后期编辑:scan()
调用另一个函数,它们可能调用也可能不调用其他函数,但它们都是同步函数,因此它们只在自己的作业完成时调用函数,前进的路只有一条。在“树”的末尾,我调用它,最后一个函数调用scheduleScan(),但不能同时运行两个作业。顺便说一句,每个作业都从scan()
开始,然后以scheduleScan(股票、周期、毫秒,'called by file.js')结束。
问题是,我相信您的扫描函数是异步的。因此,您的job.progress
函数调用scan
,然后立即调用done
,允许队列处理另一个作业
一种解决方案是,将done
回调作为参数传递给scan
和scheduleScan
函数,并在完成作业后(或出现错误时)调用它
另一个(更好的)解决方案是确保始终从scan
和scheduleScan
返回Promise
,然后等待Promise解决,然后调用done
。如果执行此操作,请确保在scheduleScan
函数中链接所有承诺返回
queue.process(1, (job, done) => {
job.progress(100).then(() => {
scan(job)
.then(done)
.catch(done)
})
})
export function scan() {
// business logic
return scheduleScan()
}
// Chain all of your promise returns. Otherwise
// the scan function will return sooner and allow done to be called
// prior to the scheduleScan function finishing it's execution
export function scheduleScan() {
return queue.getJob(..).then(() => {
....
return queue.add()...
....
return queue.add(...)
.catch(e => {
console.log(e);
// propogate errors!
throw e;
})
}
扫描函数是一个异步函数。在queue.process()
函数中,必须等待scan函数,然后调用done()
回调函数
export async function scan(job) {
// it does some calculations, then it creates a new schedule.
return scheduleScan(stock, period, milliseconds, "scan.js");
}
queue.process(1, (job, done) => {
job.progress(100).then(async() => {
await scan(job);
done();
});
});
export async function scheduleScan(stock, period, milliseconds, triggeredBy) {
let uniqueId = stringHash(stock + ":" + period);
try {
const existingJob = await queue.getJob(uniqueId);
if (!existingJob) {
const job = await addJob({
queue,
stock,
period,
uniqueId,
milliseconds,
triggeredBy
});
return job;
} else {
const jobState = await existingJob.getState();
if (jobState === "completed") {
await existingJob.remove();
const newJob = await addJob({
queue,
stock,
period,
uniqueId,
milliseconds,
triggeredBy
});
return newJob;
}
}
} catch (err) {
throw new Error(err);
}
}
export function addJob({ queue, stock, period, milliseconds, triggeredBy }) {
if (milliseconds) {
return queue.add(
{ stock, period, triggeredBy },
{ delay: milliseconds, jobId: uniqueId }
);
} else {
return queue.add({ stock, period, triggeredBy }, { jobId: uniqueId });
}
}
试试这个!我尝试使用async Wait重构代码。我找不到扫描
函数,你能帮忙吗?@MuhammadZeeshan我添加了它,我的错误。我编辑了我的问题,你能不能再检查一遍,尤其是“重要的后期编辑”部分?你的答案在这种情况下仍然适用吗?谢谢。是的,它仍然有效。从您的编辑中,我想您是说,scheduledScan
总是在scan
中的所有其他同步函数之后调用。如果是这样,那么是的,我的回答仍然有效。只要始终返回将从scan
functionalgain中的scheduleScan
返回的承诺,我的错误。第一个函数update()在扫描中,但是update()可以调用另一个函数,如finalize(),finalize()可以调用scheduleScan()。请记住,这些都是按顺序发生的,所以没有多次呼叫,我这样做是为了让我的应用程序模块化谢谢,同样的回答。如果update
调用scheduledScan
或它们之间的任意数量的函数。关键的一点是,您需要将承诺链从scheduleScan
返回到scan
函数。因此,如果scan
调用update
哪个调用finalize
。。。。。哪些调用scheduleScan
承诺链需要通过所有函数调用返回,也就是说,请确保您从每个函数返回承诺。因此,请澄清我最后的评论。例如,如果内部扫描调用update。您需要从扫描功能返回更新结果(承诺)。我已经编辑了我的问题,请您再次检查,特别是“重要的延迟编辑”部分?你的答案在这种情况下仍然适用吗?谢谢
export async function scan(job) {
// it does some calculations, then it creates a new schedule.
return scheduleScan(stock, period, milliseconds, "scan.js");
}
queue.process(1, (job, done) => {
job.progress(100).then(async() => {
await scan(job);
done();
});
});
export async function scheduleScan(stock, period, milliseconds, triggeredBy) {
let uniqueId = stringHash(stock + ":" + period);
try {
const existingJob = await queue.getJob(uniqueId);
if (!existingJob) {
const job = await addJob({
queue,
stock,
period,
uniqueId,
milliseconds,
triggeredBy
});
return job;
} else {
const jobState = await existingJob.getState();
if (jobState === "completed") {
await existingJob.remove();
const newJob = await addJob({
queue,
stock,
period,
uniqueId,
milliseconds,
triggeredBy
});
return newJob;
}
}
} catch (err) {
throw new Error(err);
}
}
export function addJob({ queue, stock, period, milliseconds, triggeredBy }) {
if (milliseconds) {
return queue.add(
{ stock, period, triggeredBy },
{ delay: milliseconds, jobId: uniqueId }
);
} else {
return queue.add({ stock, period, triggeredBy }, { jobId: uniqueId });
}
}