当我有自然同步代码但我需要调用一些异步函数时的 JS 基本设计
JS basic design when I have naturaly sync code but I need to call a few async functions
你能帮我理解 javascirpt 异步地狱吗?
我想我遗漏了一些重要的东西 ☹ 问题是 js 示例和互联网上的大多数答案只与代码的一部分有关——一小段代码。但是应用程序要复杂得多。
我不会直接用JS写,因为我更感兴趣的是设计以及如何正确地编写它。
想象一下我的应用程序中的这些功能:
InsertTestData();
SelectDataFromDB_1(‘USERS’);
SelectDataFromDB_2(‘USER_CARS’,’USERS’);
FillCollections(‘USER’,’USER_CARS’);
DoTheWork();
DeleteData();
我没有提供任何功能描述,但我认为根据名称很明显。他们需要按照具体命令执行。想象一下,我需要 运行 a select 进入数据库以获取用户,然后我需要 运行 a select 来获取这些用户的 USER_CARS。所以它必须真的按照这个顺序(考虑其他功能相同)。 问题是需要调用 6 次 Node/Mysql,这是异步的,但我需要特定顺序的结果 。那么我怎样才能正确地做到这一点呢?
这可行:
/* 无效代码 我想表达想法并保持简短 */
InsertTestData(
Mysql.query(select, data, function(err,success)
{
SelectDataFromDB_1(‘USERS’); -- in that asyn function I will call the next procedure
}
));
SelectDataFromDB_1 (
Mysql.query(select, data, function(err,success)
{
SelectDataFromDB_2(‘USERS’); -- in that asyn function I will call the next procedure
}
));
SelectDataFromDB_2 (
Mysql.query(select, data, function(err,success)
{
FillCollections (‘USERS’); -- in that asyn function I will call the next procedure
}
));
等..
我可以“轻松”链接它,但这看起来 一团糟。我的意思是真的一团糟。
如果前面的过程完成,我可以使用一些 scheduler/timmers 来安排和测试)
两个都乱七八糟的。
那么,这样做的正确方法是什么;
谢谢,
亚所
如果您使用的是最新版本的 Node,您可以使用 ES2017 的 async
/await
syntax 来获得看似同步但实际上是异步的代码。
首先,您需要 Mysql.query
的一个版本 returns 一个承诺,这很容易用 util.promisify
:
const util = require('util');
// ...
const query = util.promisify(Mysql.query);
然后,将您的代码包装在 async
函数中并使用 await
:
(async () => {
try {
await InsertTestData();
await SelectDataFromDB_1(‘USERS’);
await SelectDataFromDB_2(‘USER_CARS’,’USERS’);
await FillCollections(‘USER’,’USER_CARS’);
await DoTheWork();
await DeleteData();
} catch (e) {
// Handle the fact an error occurred...
}
})();
...您的函数是 async
函数,例如:
async InsertTestData() {
await query("INSERT INTO ...");
}
请注意 async
包装器中的 try
/catch
,处理错误是必不可少的,否则如果发生错误,您将收到未处理的拒绝通知(以及未来Node 的版本可能会终止该过程)。 (为什么 "unhandled rejections"?因为 async
函数是 promise 的语法糖;async
函数 returns 是一个 promise。)你可以使用 try
/ catch
显示,或在调用结果上使用 .catch
替代:
(async () => {
await InsertTestData();
// ...
})().catch(e => {
// Handle the fact an error occurred
});
你能帮我理解 javascirpt 异步地狱吗?
我想我遗漏了一些重要的东西 ☹ 问题是 js 示例和互联网上的大多数答案只与代码的一部分有关——一小段代码。但是应用程序要复杂得多。
我不会直接用JS写,因为我更感兴趣的是设计以及如何正确地编写它。
想象一下我的应用程序中的这些功能:
InsertTestData();
SelectDataFromDB_1(‘USERS’);
SelectDataFromDB_2(‘USER_CARS’,’USERS’);
FillCollections(‘USER’,’USER_CARS’);
DoTheWork();
DeleteData();
我没有提供任何功能描述,但我认为根据名称很明显。他们需要按照具体命令执行。想象一下,我需要 运行 a select 进入数据库以获取用户,然后我需要 运行 a select 来获取这些用户的 USER_CARS。所以它必须真的按照这个顺序(考虑其他功能相同)。 问题是需要调用 6 次 Node/Mysql,这是异步的,但我需要特定顺序的结果 。那么我怎样才能正确地做到这一点呢?
这可行: /* 无效代码 我想表达想法并保持简短 */
InsertTestData(
Mysql.query(select, data, function(err,success)
{
SelectDataFromDB_1(‘USERS’); -- in that asyn function I will call the next procedure
}
));
SelectDataFromDB_1 (
Mysql.query(select, data, function(err,success)
{
SelectDataFromDB_2(‘USERS’); -- in that asyn function I will call the next procedure
}
));
SelectDataFromDB_2 (
Mysql.query(select, data, function(err,success)
{
FillCollections (‘USERS’); -- in that asyn function I will call the next procedure
}
));
等..
我可以“轻松”链接它,但这看起来 一团糟。我的意思是真的一团糟。 如果前面的过程完成,我可以使用一些 scheduler/timmers 来安排和测试) 两个都乱七八糟的。
那么,这样做的正确方法是什么;
谢谢, 亚所
如果您使用的是最新版本的 Node,您可以使用 ES2017 的 async
/await
syntax 来获得看似同步但实际上是异步的代码。
首先,您需要 Mysql.query
的一个版本 returns 一个承诺,这很容易用 util.promisify
:
const util = require('util');
// ...
const query = util.promisify(Mysql.query);
然后,将您的代码包装在 async
函数中并使用 await
:
(async () => {
try {
await InsertTestData();
await SelectDataFromDB_1(‘USERS’);
await SelectDataFromDB_2(‘USER_CARS’,’USERS’);
await FillCollections(‘USER’,’USER_CARS’);
await DoTheWork();
await DeleteData();
} catch (e) {
// Handle the fact an error occurred...
}
})();
...您的函数是 async
函数,例如:
async InsertTestData() {
await query("INSERT INTO ...");
}
请注意 async
包装器中的 try
/catch
,处理错误是必不可少的,否则如果发生错误,您将收到未处理的拒绝通知(以及未来Node 的版本可能会终止该过程)。 (为什么 "unhandled rejections"?因为 async
函数是 promise 的语法糖;async
函数 returns 是一个 promise。)你可以使用 try
/ catch
显示,或在调用结果上使用 .catch
替代:
(async () => {
await InsertTestData();
// ...
})().catch(e => {
// Handle the fact an error occurred
});