我应该对可选但永不失败的事件使用承诺吗?
Should I use a promise for an optional but never failing event?
我有一个只能发生一次的事件。它可能永远不会发生,但我们永远不能确定它不会再发生。
具体来说,我正在等待建立连接,但我有退避机制,因此连接永远不会真正失败。
connect
方法 return 应该是一个承诺,还是应该采用处理程序和 return 一个 give up
方法,看看承诺通常是如何为事件设计的一定会发生?除了后一个选项之外的另一个论点是,从未解决的承诺是内存泄漏。
promises are generally designed for events that will certainly occur
我认为这是一种误解。 Promise API 具有在 Promise 无法解析为所需值的情况下内置拒绝 promise 的想法。
在您描述的 API 中,Promise 肯定是有保证的。如果您担心 Promise 永远不会被解决,您的 API 可以提供一个可选的超时,在此之后 Promise 会拒绝。或者,如果您希望 Promise 可由调用者取消,则返回 Promise 和 cancel 方法都是合适的。
后者可能看起来像:
type CancellableConnection = {
cancel: () => void;
connectionPromise: Promise<Connection>;
};
function establishConnection(opts): CancellableConnection {
let cancelled = false;
return {
cancel: () => { cancelled = true; },
connectionPromise: new Promise((resolve, reject) => {
let connection;
while (!cancelled && !connection) {
// try to connect with exponential backoff
}
if (cancelled) {
reject();
}
resolve(connection);
})
}
}
const { cancel, connectionPromise } = establishConnection(opts);
try {
const timeoutId = setTimeout(cancel, 60000); // cancel after a minute;
const connection = await connectionPromise;
clearTimeout(timeoutId);
// use connection
} catch () {
// handle connection
}
遗漏了许多细节,如果超时是您需要处理的唯一情况,那么通过竞速基于 setTimeout
的承诺来处理 establishConnection
调用内部的超时会更简单.
我有一个只能发生一次的事件。它可能永远不会发生,但我们永远不能确定它不会再发生。
具体来说,我正在等待建立连接,但我有退避机制,因此连接永远不会真正失败。
connect
方法 return 应该是一个承诺,还是应该采用处理程序和 return 一个 give up
方法,看看承诺通常是如何为事件设计的一定会发生?除了后一个选项之外的另一个论点是,从未解决的承诺是内存泄漏。
promises are generally designed for events that will certainly occur
我认为这是一种误解。 Promise API 具有在 Promise 无法解析为所需值的情况下内置拒绝 promise 的想法。
在您描述的 API 中,Promise 肯定是有保证的。如果您担心 Promise 永远不会被解决,您的 API 可以提供一个可选的超时,在此之后 Promise 会拒绝。或者,如果您希望 Promise 可由调用者取消,则返回 Promise 和 cancel 方法都是合适的。
后者可能看起来像:
type CancellableConnection = {
cancel: () => void;
connectionPromise: Promise<Connection>;
};
function establishConnection(opts): CancellableConnection {
let cancelled = false;
return {
cancel: () => { cancelled = true; },
connectionPromise: new Promise((resolve, reject) => {
let connection;
while (!cancelled && !connection) {
// try to connect with exponential backoff
}
if (cancelled) {
reject();
}
resolve(connection);
})
}
}
const { cancel, connectionPromise } = establishConnection(opts);
try {
const timeoutId = setTimeout(cancel, 60000); // cancel after a minute;
const connection = await connectionPromise;
clearTimeout(timeoutId);
// use connection
} catch () {
// handle connection
}
遗漏了许多细节,如果超时是您需要处理的唯一情况,那么通过竞速基于 setTimeout
的承诺来处理 establishConnection
调用内部的超时会更简单.