如何从 React 应用程序停止 node.js 上的 运行 异步功能?
How to stop running async function on node.js from react application?
React 应用程序可以运行 node.js 批量准备数据并将信息发送到数据库的功能。
这需要很多时间,我想添加直接从 React 应用程序停止此功能的功能。
const getShopifyOrders = require('./shopify');
const getTrack = require('./tracking');
const Order = require('./model');
async function addOrdersToDB(limit) {
try {
// Get latest order from DB
let latestOrd = await Order.findOne().sort('-order_number');
do {
// Get Shopify Orders
let orders = await getShopifyOrders(
latestOrd ? latestOrd.order_id : 0,
limit
);
latestOrd = orders[0] ? orders[orders.length - 1] : undefined;
// Update array with tracking status
let fullArray = await getTrack(orders);
// Add to DB
let ins = await Order.insertMany(fullArray, { ordered: false });
console.log(`Added ${ins.length} entries`);
} while (latestOrd);
} catch (err) {
console.log(err);
}
}
module.exports = addOrdersToDB;
我尝试了很多东西来包含在这个函数中,包括:
while 循环:在函数外添加变量 - if 'true' - 运行 代码,如果不是 - return - 它只是不起作用(使用 socket.IO)
更改了变量
setTimeout(也称为 setInterval),触发 react 的 clearTimeout 函数:这不起作用,因为 setTimeout 和 setInterval 在异步函数中不起作用
之后:
- 制作(实际上很喜欢 Whosebug 上的这里)新函数来保证 setTimeout 能够在异步函数中使用:
const setTimeout2 = (callback, ms) => {
return new Promise(
resolve =>
(to = setTimeout(() => {
callback();
resolve();
}, ms))
);
};
async function addOrdersToDB(limit) {
do {
await setTimeout2(async () => {
try {
// some code here
} catch (err) {
console.log(err);
}
}, 400);
} while (latestOrderExist);
}
function clearTO() {
setTimeout(() => {
console.log('clearTO');
clearTimeout(to);
}, 3000);
}
出于某种原因,这不会迭代。
有解决办法吗?
谢谢!
要中止 do/while
循环,您需要向该循环添加一个额外的测试,该测试是一些可以从外界修改的变量。另外,请注意附加测试仅适用于此处,因为您在循环内使用 await
。如果循环内没有 await
,那么循环将是完全同步的,并且在循环为 运行 时无法从循环外部更改变量(因为 nodejs 的单-螺纹)。
由于这是一个服务器(全局变量通常不好),我假设我们不应该使用全局变量。因此,相反,我会将 addOrdersToDB()
重组为 return 一个数据结构,其中包含现有版本 returns 的承诺和调用者可以调用以停止当前版本的 abort()
函数加工。这也允许对 addOrdersToDB()
的多个单独调用是 运行,每个调用都有自己单独的 abort()
方法。
function addOrdersToDB(limit) {
let stop = false;
function abort() {
stop = true;
}
async function run() {
try {
// Get latest order from DB
let latestOrd = await Order.findOne().sort('-order_number');
do {
// Get Shopify Orders
let orders = await getShopifyOrders(
latestOrd ? latestOrd.order_id : 0,
limit
);
latestOrd = orders[0] ? orders[orders.length - 1] : undefined;
// Update array with tracking status
let fullArray = await getTrack(orders);
// Add to DB
let ins = await Order.insertMany(fullArray, { ordered: false });
console.log(`Added ${ins.length} entries`);
} while (!stop && latestOrd);
// make resolved value be a boolean that indicates
// whether processing was stopped with more work still pending
return !!(latestOrd && stop);
} catch (err) {
// log error and rethrow so caller gets error propagation
console.log(err);
throw err;
}
}
return {
promise: run(),
abort: abort
}
}
因此,要使用它,您必须更改调用 addOrdersToDB()
的方式(因为它不再 return 只是一个承诺)并且您必须捕获 abort()
函数,它 returns。然后,您的代码的其他部分可以调用 abort()
函数,然后它将翻转内部 stop
变量,这将导致您的 do/while
循环停止任何进一步的迭代。
请注意,这不会停止 do/while
循环当前迭代内的异步处理 - 它只会停止循环的任何进一步迭代。
请注意,我还更改了您的 catch
块,以便它重新抛出错误,以便调用者看到 if/when 出现错误。
并且,函数的解析值是内部 stop
变量,因此调用者可以查看循环是否中止。 true
已解决的值意味着循环已中止,还有更多工作要做。
这是该函数的一个附加版本,它创造了更多机会使其在函数内和循环内的 await
操作之间停止。这仍然不会中止可能正在进行的单个数据库操作 - 您必须检查您的数据库是否支持此类操作,如果支持,如何使用它。
function addOrdersToDB(limit) {
let stop = false;
function abort() {
stop = true;
}
async function run() {
try {
// Get latest order from DB
let latestOrd = await Order.findOne().sort('-order_number');
if (!stop) {
do {
// Get Shopify Orders
let orders = await getShopifyOrders(
latestOrd ? latestOrd.order_id : 0,
limit
);
latestOrd = orders[0] ? orders[orders.length - 1] : undefined;
if (stop) break;
// Update array with tracking status
let fullArray = await getTrack(orders);
if (stop) break;
// Add to DB
let ins = await Order.insertMany(fullArray, { ordered: false });
console.log(`Added ${ins.length} entries`);
} while (!stop && latestOrd);
}
// make resolved value be a boolean that indicates
// whether processing was stopped with more work still pending
return !!(latestOrd && stop);
} catch (err) {
// log and rethrow error so error gets propagated back to cller
console.log(err);
throw err;
}
}
return {
promise: run(),
abort: abort
}
}
React 应用程序可以运行 node.js 批量准备数据并将信息发送到数据库的功能。 这需要很多时间,我想添加直接从 React 应用程序停止此功能的功能。
const getShopifyOrders = require('./shopify');
const getTrack = require('./tracking');
const Order = require('./model');
async function addOrdersToDB(limit) {
try {
// Get latest order from DB
let latestOrd = await Order.findOne().sort('-order_number');
do {
// Get Shopify Orders
let orders = await getShopifyOrders(
latestOrd ? latestOrd.order_id : 0,
limit
);
latestOrd = orders[0] ? orders[orders.length - 1] : undefined;
// Update array with tracking status
let fullArray = await getTrack(orders);
// Add to DB
let ins = await Order.insertMany(fullArray, { ordered: false });
console.log(`Added ${ins.length} entries`);
} while (latestOrd);
} catch (err) {
console.log(err);
}
}
module.exports = addOrdersToDB;
我尝试了很多东西来包含在这个函数中,包括:
while 循环:在函数外添加变量 - if 'true' - 运行 代码,如果不是 - return - 它只是不起作用(使用 socket.IO)
更改了变量setTimeout(也称为 setInterval),触发 react 的 clearTimeout 函数:这不起作用,因为 setTimeout 和 setInterval 在异步函数中不起作用
之后:
- 制作(实际上很喜欢 Whosebug 上的这里)新函数来保证 setTimeout 能够在异步函数中使用:
const setTimeout2 = (callback, ms) => {
return new Promise(
resolve =>
(to = setTimeout(() => {
callback();
resolve();
}, ms))
);
};
async function addOrdersToDB(limit) {
do {
await setTimeout2(async () => {
try {
// some code here
} catch (err) {
console.log(err);
}
}, 400);
} while (latestOrderExist);
}
function clearTO() {
setTimeout(() => {
console.log('clearTO');
clearTimeout(to);
}, 3000);
}
出于某种原因,这不会迭代。
有解决办法吗? 谢谢!
要中止 do/while
循环,您需要向该循环添加一个额外的测试,该测试是一些可以从外界修改的变量。另外,请注意附加测试仅适用于此处,因为您在循环内使用 await
。如果循环内没有 await
,那么循环将是完全同步的,并且在循环为 运行 时无法从循环外部更改变量(因为 nodejs 的单-螺纹)。
由于这是一个服务器(全局变量通常不好),我假设我们不应该使用全局变量。因此,相反,我会将 addOrdersToDB()
重组为 return 一个数据结构,其中包含现有版本 returns 的承诺和调用者可以调用以停止当前版本的 abort()
函数加工。这也允许对 addOrdersToDB()
的多个单独调用是 运行,每个调用都有自己单独的 abort()
方法。
function addOrdersToDB(limit) {
let stop = false;
function abort() {
stop = true;
}
async function run() {
try {
// Get latest order from DB
let latestOrd = await Order.findOne().sort('-order_number');
do {
// Get Shopify Orders
let orders = await getShopifyOrders(
latestOrd ? latestOrd.order_id : 0,
limit
);
latestOrd = orders[0] ? orders[orders.length - 1] : undefined;
// Update array with tracking status
let fullArray = await getTrack(orders);
// Add to DB
let ins = await Order.insertMany(fullArray, { ordered: false });
console.log(`Added ${ins.length} entries`);
} while (!stop && latestOrd);
// make resolved value be a boolean that indicates
// whether processing was stopped with more work still pending
return !!(latestOrd && stop);
} catch (err) {
// log error and rethrow so caller gets error propagation
console.log(err);
throw err;
}
}
return {
promise: run(),
abort: abort
}
}
因此,要使用它,您必须更改调用 addOrdersToDB()
的方式(因为它不再 return 只是一个承诺)并且您必须捕获 abort()
函数,它 returns。然后,您的代码的其他部分可以调用 abort()
函数,然后它将翻转内部 stop
变量,这将导致您的 do/while
循环停止任何进一步的迭代。
请注意,这不会停止 do/while
循环当前迭代内的异步处理 - 它只会停止循环的任何进一步迭代。
请注意,我还更改了您的 catch
块,以便它重新抛出错误,以便调用者看到 if/when 出现错误。
并且,函数的解析值是内部 stop
变量,因此调用者可以查看循环是否中止。 true
已解决的值意味着循环已中止,还有更多工作要做。
这是该函数的一个附加版本,它创造了更多机会使其在函数内和循环内的 await
操作之间停止。这仍然不会中止可能正在进行的单个数据库操作 - 您必须检查您的数据库是否支持此类操作,如果支持,如何使用它。
function addOrdersToDB(limit) {
let stop = false;
function abort() {
stop = true;
}
async function run() {
try {
// Get latest order from DB
let latestOrd = await Order.findOne().sort('-order_number');
if (!stop) {
do {
// Get Shopify Orders
let orders = await getShopifyOrders(
latestOrd ? latestOrd.order_id : 0,
limit
);
latestOrd = orders[0] ? orders[orders.length - 1] : undefined;
if (stop) break;
// Update array with tracking status
let fullArray = await getTrack(orders);
if (stop) break;
// Add to DB
let ins = await Order.insertMany(fullArray, { ordered: false });
console.log(`Added ${ins.length} entries`);
} while (!stop && latestOrd);
}
// make resolved value be a boolean that indicates
// whether processing was stopped with more work still pending
return !!(latestOrd && stop);
} catch (err) {
// log and rethrow error so error gets propagated back to cller
console.log(err);
throw err;
}
}
return {
promise: run(),
abort: abort
}
}