在几秒钟后超时async/await函数



我创建了一个函数来使用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的示例。与setTimeout赛跑,但我不能把它放在实践中,我的尝试总是在控制台上得到一个UnhandledPromiseRejectionWarning,所以我认为这不是正确的方式。

谁能给我举个例子怎么做?

当然性能的答案是伟大的,但我建议不要纠缠超时逻辑与您的功能。这些都是通用的东西,应该与连接逻辑分开实现。

我认为下面的方法是好的,因为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)

您可以在connectString上设置超时:

对于Oracle Client 19c,超时可以通过Easy Connect字符串传递,例如15秒后超时:"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)

(也是文档链接的一部分)

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);
})
};

最新更新