大家好,我有一个错误,真的让我很紧张,哈哈。
所以基本上我有一个 nodejs 应用程序向电子商务网站发出请求以检索订单,我们的流程基本上是这样的:我们向这个网站发出 GET 请求,我们检索等待接受的订单,然后我们“接受”它们我们可以读取收货地址,然后我们解析订单、其产品和收货地址,以便我们的系统可以注册它。
所有这一切现在每 5 分钟完成一次,每 10 分钟完成一次,我们减少它会减少丢失的订单数量 :(,所以无论如何,这是通过我们在 NodeJS 上安排的 cron 作业完成的。这是 cron: */5 * * * *
这个应用程序是用 NodeJs LTS 编写的,并在 ubuntu docker 容器中运行。
这是安排 cron 的代码:
export function createOrderCrons(): void
{
cron.schedule(
process.env.ORDER_REGISTER_TIMELAPSE,
async () =>
{
await consumeRegisterOrders();
cronLogger.info('Runing get orders task');
},
cronOptions
);
cron.schedule(..........);//redacted
}
这是 cron 调用的函数:export async function consumeRegisterOrders(): Promise<void>
{
try
{
await Axios.post(`${process.env.HOST}/orders/`);
cronLogger.info(`${process.env.HOST}/orders/`);
}
catch (error)
{
if (!HTTP.TOO_MANY_REQUESTS)
{
errorLogger.info('Consume Register Orders endpoint error:', error);
}
}
}
这是读取订单的代码:export async function getOrders(auth: any): Promise<any[]>
{
try
{
const orders: IOrder[] = [];
const ordersToGet: string[] = [];
const res = await miraklApi.get(
'/orders?order_state_codes=WAITING_ACCEPTANCE&paginate=false',
{
headers: auth.headers
}
);
errorLogger.info(`orders retrieved from waiting_acceptance ${res.data.orders.length}`);
for(let i = 0; i < res.data.orders.length; i++)
{
const order = res.data.orders[i];
order.warehouseSialId = auth.warehouseSialId;
await validateOrder(order, true, auth);
await ordersToGet.push(order.order_id);
}
errorLogger.info(`orders to get with folios ${ordersToGet.length}`);
if(ordersToGet.length > 0)
{
const response = await miraklApi.get(
`/orders?order_ids=${ordersToGet.join(',')}&paginate=false`,
{
headers: auth.headers
}
);
errorLogger.info(`orders retrieved with address ${response.data.orders.length}`);
await orders.push(...response.data.orders);
}
errorLogger.info(`orders to return ${orders.length}`);
return await orders;
}
catch (error)
{
errorLogger.info(`error inside of get orders function ${error}`);
return [];
}
}
这是端点级别的代码:ordersRouter.post(
'/',
async(ctx: Context): Promise < void > => {
try {
const auth = {
headers: {
// eslint-disable-next-line @typescript-eslint/naming-convention
Authorization: `${
process.env.MIRAKL_API_TOKEN
}`
},
warehouseSialId: process.env.WAREHOUSE_ID
};
const orders = await getOrders(auth);
for (let i = 0; i < orders.length; i++) {
const order = orders[i];
let task: ITask = null;
try {
order.warehouseSialId = auth.warehouseSialId;
const products: IProduct[] = await mapToMindiProducts(order.order_lines);
const mappedOrder = await mapToMindiOrder(order, products);
await registerOrder(mappedOrder);
if (onfleetIsEnabled) {
task = await getOnfleetTaskById(order.shipping.externalId);
}
} catch (error) {
errorLogger.info(`error inside of one cycle to register an order ${JSON.stringify(error)}`);
continue;
}
errorLogger.info(`before change status to shipped ${order.order_id}`);
await sendTaskToMirakl(task, order, auth);
}
} catch (e) {
errorLogger.info(`error at endpoint /orders ${JSON.stringify(e)}`);
}
ctx.status = HTTP.OK;
}
);
这里是发生了什么的一瞥,你可以看到我在第一次迭代中接受了两个订单然后在第二次迭代中的另一个它只接受订单并且它永远不会到达这个 getOrders 函数之外,并且日志中也没有错误:(
这里似乎没有确定的模式,当我们在 10 分钟配置 cron 时,我注意到一个模式,即 cron 每次运行命令时都不会使其脱离 getOrders 函数并且永远不会注册。
最佳答案
您应该使用 try catch 来结束函数 consumeRegisterOrders
因为它可能会引发错误并且您的计划作业将被终止。
export function createOrderCrons(): void {
cron.schedule(process.env.ORDER_REGISTER_TIMELAPSE, async () => {
try {
await consumeRegisterOrders();
cronLogger.info('Runing get orders task');
} catch (err) {
console.error(err);
}
}, cronOptions);
}
关于javascript - Cronjob 停止执行 nodejs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64884665/