同步代码中似乎没有 运行 异步函数
async function doesn't seem to run inside sync code
我试图创建一个连接到数据库的命令,我创建了一个小的 CLI 脚本,循环遍历特定文件夹中的文件以获取命令 class 模块
我的问题是,在我的一个命令中,我试图连接到 sequelize,但它似乎什么也没做。我没有得到控制台的输出,它甚至似乎也没有尝试连接
这可能是因为我仍然在努力弄清楚如何正确地执行同步/异步/等待...注意我如何使用 glob.sync
因为我想同步循环文件,但是在我的命令中,我需要使用 await
连接到数据库
cli.js
:
#! /usr/bin/env node
const patterns = [
'./node_modules/unity/src/commands/**/*.js',
'./src/commands/**/*.js',
]
const glob = require('glob')
const path = require('path')
const yargs = require('yargs')
const signature = yargs.argv._[0]
const process = require('process')
patterns.forEach(pattern => {
glob.sync(pattern).forEach(file => {
const commandPath = path.resolve(file)
const command = require(commandPath)
if (command.signature == signature) {
command.argv = yargs.argv
command.run()
process.exit()
}
})
})
console.log('Command not found.')
这是 commands
文件夹之一中的示例命令:
const { Sequelize } = require('sequelize')
class MigrateCommand {
static signature = 'migrate'
static argv = {}
static run() {
const sequelize = new Sequelize({
dialect: 'mysql',
host: 'localhost',
port: 3306,
database: 'dio_unity2',
username: 'root',
password: '',
})
const connect = async () => {
try {
await sequelize.authenticate()
console.log('Connection successful.')
}
catch (error) {
console.error('Unable to connect.', error)
}
}
connect()
console.log('migrate run complete')
}
}
module.exports = MigrateCommand
我已经设置了 npx,所以我可以 运行 npx unity migrate
它会根据 migrate
签名
调用这个命令
现在我的控制台应该显示 connection successful
或 unable to connect
,然后是 migrate run complete
,但我在控制台中看到的只是 migrate run complete
。就好像它根本就没有尝试连接...
我不知道我做错了什么。
You can't make an asynchronous process synchronous without spawning a new thread and synchronously waiting on it. (There's an npm
package that does that, via execSync
.)
但这里的好消息是 您的代码中没有必要。您想串联做事,但是串联做事与同步[=]不完全一样42=]。方法如下:
首先,run
无法使它通过 authenticate
同步启动的异步进程。因此,run
应该只是 async
(我们不需要 connect
):
static async run() {
const sequelize = new Sequelize({
dialect: 'mysql',
host: 'localhost',
port: 3306,
database: 'dio_unity2',
username: 'root',
password: '',
})
try {
await sequelize.authenticate()
console.log('Connection successful.')
} catch (error) {
console.error('Unable to connect.', error)
}
console.log('migrate run complete')
}
接下来,在脚本中,我们使用 async
函数遍历您的模式和文件:
(async () => {
for (const pattern of patterns) {
for (const file of glob.sync(pattern)) {
const commandPath = path.resolve(file)
const command = require(commandPath)
if (command.signature == signature) {
command.argv = yargs.argv
await command.run() // *** Note the `await`
process.exit()
}
}
}
console.log("Command not found.")
})();
那是异步工作,但一个接一个(串联)。
如果是我,我不会使用 process.exit()
来终止进程,这是一种非常激进的进程终止形式,可能会阻止某些事情完成 (details here),并且可能对于以后进行代码维护的人来说不像其他选择那样清楚。现在我们已经将代码放在包装函数中,我只是 return 退出函数来打破循环:
await command.run();
return;
我试图创建一个连接到数据库的命令,我创建了一个小的 CLI 脚本,循环遍历特定文件夹中的文件以获取命令 class 模块
我的问题是,在我的一个命令中,我试图连接到 sequelize,但它似乎什么也没做。我没有得到控制台的输出,它甚至似乎也没有尝试连接
这可能是因为我仍然在努力弄清楚如何正确地执行同步/异步/等待...注意我如何使用 glob.sync
因为我想同步循环文件,但是在我的命令中,我需要使用 await
cli.js
:
#! /usr/bin/env node
const patterns = [
'./node_modules/unity/src/commands/**/*.js',
'./src/commands/**/*.js',
]
const glob = require('glob')
const path = require('path')
const yargs = require('yargs')
const signature = yargs.argv._[0]
const process = require('process')
patterns.forEach(pattern => {
glob.sync(pattern).forEach(file => {
const commandPath = path.resolve(file)
const command = require(commandPath)
if (command.signature == signature) {
command.argv = yargs.argv
command.run()
process.exit()
}
})
})
console.log('Command not found.')
这是 commands
文件夹之一中的示例命令:
const { Sequelize } = require('sequelize')
class MigrateCommand {
static signature = 'migrate'
static argv = {}
static run() {
const sequelize = new Sequelize({
dialect: 'mysql',
host: 'localhost',
port: 3306,
database: 'dio_unity2',
username: 'root',
password: '',
})
const connect = async () => {
try {
await sequelize.authenticate()
console.log('Connection successful.')
}
catch (error) {
console.error('Unable to connect.', error)
}
}
connect()
console.log('migrate run complete')
}
}
module.exports = MigrateCommand
我已经设置了 npx,所以我可以 运行 npx unity migrate
它会根据 migrate
签名
现在我的控制台应该显示 connection successful
或 unable to connect
,然后是 migrate run complete
,但我在控制台中看到的只是 migrate run complete
。就好像它根本就没有尝试连接...
我不知道我做错了什么。
You can't make an asynchronous process synchronous without spawning a new thread and synchronously waiting on it. (There's an npm
package that does that, via execSync
.)
但这里的好消息是 您的代码中没有必要。您想串联做事,但是串联做事与同步[=]不完全一样42=]。方法如下:
首先,run
无法使它通过 authenticate
同步启动的异步进程。因此,run
应该只是 async
(我们不需要 connect
):
static async run() {
const sequelize = new Sequelize({
dialect: 'mysql',
host: 'localhost',
port: 3306,
database: 'dio_unity2',
username: 'root',
password: '',
})
try {
await sequelize.authenticate()
console.log('Connection successful.')
} catch (error) {
console.error('Unable to connect.', error)
}
console.log('migrate run complete')
}
接下来,在脚本中,我们使用 async
函数遍历您的模式和文件:
(async () => {
for (const pattern of patterns) {
for (const file of glob.sync(pattern)) {
const commandPath = path.resolve(file)
const command = require(commandPath)
if (command.signature == signature) {
command.argv = yargs.argv
await command.run() // *** Note the `await`
process.exit()
}
}
}
console.log("Command not found.")
})();
那是异步工作,但一个接一个(串联)。
如果是我,我不会使用 process.exit()
来终止进程,这是一种非常激进的进程终止形式,可能会阻止某些事情完成 (details here),并且可能对于以后进行代码维护的人来说不像其他选择那样清楚。现在我们已经将代码放在包装函数中,我只是 return 退出函数来打破循环:
await command.run();
return;