超时 async/await 几秒后起作用
Timeout async/await functions after a few seconds
我创建了一个使用oracledb获取Oracle连接的函数,但是在少数情况下,即使他没有获取到连接oracledb也没有抛出异常,显然他正在尝试无限连接。
const getConnection = async (): Promise<oracledb.Connection | undefined> => {
let connection;
try {
connection = await oracledb.getConnection({
user: process.env.DB_LOGIN,
password: process.env.DB_PASSWORD,
connectString: process.env.DB_STRING_CONNECTION,
});
} catch (err) {
console.error(err);
}
return connection;
};
我看到一些使用 Promise.racing 和 setTimeout 的示例,但我无法将其付诸实践,我的尝试总是在控制台上出现 UnhandledPromiseRejectionWarning,所以我认为这不是正确的方法。
任何人都可以告诉我如何做的例子吗?
Promise.race
如果实施得当,应该可以正常工作。将 getConnection
与解决(而不是拒绝)的 Promise 竞赛,并确保链接到 .catch
.
const getConnection = (): Promise<oracledb.Connection | undefined> => {
return Promise.race([
oracledb.getConnection({
user: process.env.DB_LOGIN,
password: process.env.DB_PASSWORD,
connectString: process.env.DB_STRING_CONNECTION,
}),
new Promise((resolve) => { setTimeout(resolve, 5000); })
])
.catch((error) => {
// this will only be entered into if getConnection rejects (and not if it times out)
console.log(error);
})
};
您似乎可以在 connectString
:
上设置超时
With Oracle Client 19c, timeouts can be passed in Easy Connect strings, for example to timeout after 15 seconds: "mydbmachine.example.com/orclpdb1?connect_timeout=15"
http://oracle.github.io/node-oracledb/doc/api.html#dbcalltimeouts
这意味着您可以简单地构造带有超时的字符串:
connectString: process.env.DB_STRING_CONNECTION + '?connect_timeout=15',
当然有更好的方法来处理字符串的构造。
您可以使用此连接字符串格式来指定没有 19c 客户端的超时:
(DESCRIPTION=(CONNECT_TIMEOUT=15 ms)(ADDRESS=(PROTOCOL=TCP)(HOST=mymachine.example.com)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)))(RETRY_COUNT=3)
(也是链接文档的一部分)
CertainPerformance 的回答很好,但我建议不要将超时逻辑与您的函数纠缠在一起。这些是通用的东西,应该与您的连接逻辑分开实现。
我认为下面的方法很好,因为 timeout
可由调用者配置,允许他们决定任务应等待多长时间。
const sleep = ms =>
new Promise(r => setTimeout(r, ms))
const timeout = (p, ms) =>
Promise.race([
p,
new Promise((_, r) => sleep(ms).then(_ => r(Error("timeout"))))
])
const fakeConnect = () =>
sleep(2000).then(_ => "connected!")
// Example 1: 500 ms timeout
timeout(fakeConnect(), 500)
.then(console.log, console.error) // Error: timeout
// Example 2: 10 second timeout
timeout(fakeConnect(), 10000) // connected!
.then(console.log, console.error)
我创建了一个使用oracledb获取Oracle连接的函数,但是在少数情况下,即使他没有获取到连接oracledb也没有抛出异常,显然他正在尝试无限连接。
const getConnection = async (): Promise<oracledb.Connection | undefined> => {
let connection;
try {
connection = await oracledb.getConnection({
user: process.env.DB_LOGIN,
password: process.env.DB_PASSWORD,
connectString: process.env.DB_STRING_CONNECTION,
});
} catch (err) {
console.error(err);
}
return connection;
};
我看到一些使用 Promise.racing 和 setTimeout 的示例,但我无法将其付诸实践,我的尝试总是在控制台上出现 UnhandledPromiseRejectionWarning,所以我认为这不是正确的方法。
任何人都可以告诉我如何做的例子吗?
Promise.race
如果实施得当,应该可以正常工作。将 getConnection
与解决(而不是拒绝)的 Promise 竞赛,并确保链接到 .catch
.
const getConnection = (): Promise<oracledb.Connection | undefined> => {
return Promise.race([
oracledb.getConnection({
user: process.env.DB_LOGIN,
password: process.env.DB_PASSWORD,
connectString: process.env.DB_STRING_CONNECTION,
}),
new Promise((resolve) => { setTimeout(resolve, 5000); })
])
.catch((error) => {
// this will only be entered into if getConnection rejects (and not if it times out)
console.log(error);
})
};
您似乎可以在 connectString
:
With Oracle Client 19c, timeouts can be passed in Easy Connect strings, for example to timeout after 15 seconds: "mydbmachine.example.com/orclpdb1?connect_timeout=15"
http://oracle.github.io/node-oracledb/doc/api.html#dbcalltimeouts
这意味着您可以简单地构造带有超时的字符串:
connectString: process.env.DB_STRING_CONNECTION + '?connect_timeout=15',
当然有更好的方法来处理字符串的构造。
您可以使用此连接字符串格式来指定没有 19c 客户端的超时:
(DESCRIPTION=(CONNECT_TIMEOUT=15 ms)(ADDRESS=(PROTOCOL=TCP)(HOST=mymachine.example.com)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)))(RETRY_COUNT=3)
(也是链接文档的一部分)
CertainPerformance 的回答很好,但我建议不要将超时逻辑与您的函数纠缠在一起。这些是通用的东西,应该与您的连接逻辑分开实现。
我认为下面的方法很好,因为 timeout
可由调用者配置,允许他们决定任务应等待多长时间。
const sleep = ms =>
new Promise(r => setTimeout(r, ms))
const timeout = (p, ms) =>
Promise.race([
p,
new Promise((_, r) => sleep(ms).then(_ => r(Error("timeout"))))
])
const fakeConnect = () =>
sleep(2000).then(_ => "connected!")
// Example 1: 500 ms timeout
timeout(fakeConnect(), 500)
.then(console.log, console.error) // Error: timeout
// Example 2: 10 second timeout
timeout(fakeConnect(), 10000) // connected!
.then(console.log, console.error)