我尝试为amqplib / callback_api编写简单的事件发射器包装。当兔子不可用或没有连接时,我无法处理情景警示。
我有方法getConnect
返回Promise,它在建立连接时解析。但是,如果连接被拒绝,Promise显然会拒绝。如何强制这种方法在不建立连接的情况下重新连接
/**
* Async method getConnect for connection
* @returns {Promise<*>}
*/
getConnect = async () => {
return new Promise((resolve, reject) => {
amqp.connect(this.config.url, async function(err, conn) {
if (err) {
reject(err);
}
resolve(conn);
})
})
};
整个代码在https://github.com/kimonniez/rabbitEE
也许,我已经很困了,但我完全感到困惑:)预先感谢!
答案 0 :(得分:1)
Promise
包裹在Observable
内 Promise
不能处理“重试” 逻辑。如果要这样做,则应使用rxjs
library查看 Observables 。这样可以在捕获错误的同时使用任意时间间隔重试。
const { from, interval, of } = rxjs;
const { catchError, mergeMap, tap, skipWhile, take } = rxjs.operators;
const THRESHOLD = 3;
const RETRY_INTERVAL = 1000;
// Equivalent to 'amqp.connect'
const functionThatThrows = number =>
number < THRESHOLD
? Promise.reject(new Error("ERROR"))
: Promise.resolve("OK");
// Equivalent to `getConnect`
const getConnect = () =>
interval(RETRY_INTERVAL)
.pipe(
mergeMap(x => from(functionThatThrows(x)).pipe(catchError(e => of(e)))),
skipWhile(x => {
const isError = x instanceof Error;
if (isError) console.log('Found error. Retrying...');
return isError;
}),
take(1)
).toPromise();
// Resolve only if the inner Promise is resolved
getConnect().then(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>
interval
中的1000
创建源。表示它将每秒重试amqp.connect
,相当于我的示例中的functionThatThrows
catchError
运算符捕获错误并返回错误Promise
已解决但未被拒绝的情况下,您才能解决 take(1)
toPromise
实用程序功能将可观察的转换为诺言then
一样附加Promise
答案 1 :(得分:0)
如果您只想一直尝试连接直到建立连接,则可以将getConnect
方法包装到新的keepConnect
方法中:
keepConnect = async () => {
while (true) {
try {
let conn = await getConnect()
return conn
} catch (e) {}
}
}
但是我认为最好通过更改while
条件来实现“尝试连接n次”之类的方法。通常,“ while true”解决方案不是干净的,可能会导致性能下降,并可能减慢事件循环的速度(假设connect方法总是在几毫秒内返回错误)。
您还可以使用keepConnect
包装器来实现连接尝试之间的逐步延迟系统。
如果您想在连接断开时重新连接,则与Rabbit(我不知道)及其事件有关。