未能在我的 websocket 确认重新连接逻辑中解决承诺
Failing to resolve promise within my websocket acknowledgement reconnect logic
我有一个自定义连接函数,它创建了一个承诺,一旦我发出 websocket 调用并收到确认,我就想解决这个问题。远程服务器可能已启动,也可能已关闭,但如果它不可用,我想继续尝试直到成功。
const socketIOClient = require('socket.io-client');
function createTimeoutCallback(callback)
{
let called = false;
let timerID = setTimeout(() => {
if (called) return;
called = true;
callback(new TimeoutError());
},
60*1000);
return function() {
if (called) return;
called = true;
clearTimeout(timerID);
callback.apply(this, arguments);
}
}
async function myConnect()
{
let mysocket = socketIOClient(url);
return new Promise((resolve, reject) => {
mysocket.emit('clientconnect', args, createTimeoutCallback((resp) => {
if (!(resp instanceof TimeoutError)) {
// SUCCESS
doSomething();
resolve();
}
// We timed out, try again
else {
mysocket.close();
setTimeout(myConnect, 60*1000);
}
}));
});
}
await connect();
// doSomething() gets called but we never get here
在上面的代码中,如果端点可用,则一切正常。但是当 (1) 我等待它的承诺时,我永远不会从 myConnect() 函数返回; (2) 该功能需要进行多次连接尝试(例如,服务器最初未启动); (3) 端点终于重新上线,连接成功。我怀疑这与我在重新连接尝试时放弃最初的承诺有关,但我不想拒绝它,否则操作会过早失败。
我确实找到了一个解决方法,它依赖于一个嵌入式函数。使用这种技术,只有一个始终可访问且在范围内的承诺,并且基于计时器的递归(即,不是基于堆栈的)始终包含在永不放弃的单个承诺中。我在 Jaromanda 回答之前将其放在一起,所以我无法确认他的解决方案是否有效。
async function myConnect()
{
return new Promise((resolve, reject) => {
function innerConnect()
{
let mysocket = socketIOClient(url);
mysocket.emit('clientconnect', args, createTimeoutCallback((resp) => {
if (!(resp instanceof TimeoutError)) {
// SUCCESS
doSomething();
resolve();
}
// We timed out, try again
else {
mysocket.close();
setTimeout(innerConnect, 60*1000);
}
}));
}
innerConnect();
});
}
我有一个自定义连接函数,它创建了一个承诺,一旦我发出 websocket 调用并收到确认,我就想解决这个问题。远程服务器可能已启动,也可能已关闭,但如果它不可用,我想继续尝试直到成功。
const socketIOClient = require('socket.io-client');
function createTimeoutCallback(callback)
{
let called = false;
let timerID = setTimeout(() => {
if (called) return;
called = true;
callback(new TimeoutError());
},
60*1000);
return function() {
if (called) return;
called = true;
clearTimeout(timerID);
callback.apply(this, arguments);
}
}
async function myConnect()
{
let mysocket = socketIOClient(url);
return new Promise((resolve, reject) => {
mysocket.emit('clientconnect', args, createTimeoutCallback((resp) => {
if (!(resp instanceof TimeoutError)) {
// SUCCESS
doSomething();
resolve();
}
// We timed out, try again
else {
mysocket.close();
setTimeout(myConnect, 60*1000);
}
}));
});
}
await connect();
// doSomething() gets called but we never get here
在上面的代码中,如果端点可用,则一切正常。但是当 (1) 我等待它的承诺时,我永远不会从 myConnect() 函数返回; (2) 该功能需要进行多次连接尝试(例如,服务器最初未启动); (3) 端点终于重新上线,连接成功。我怀疑这与我在重新连接尝试时放弃最初的承诺有关,但我不想拒绝它,否则操作会过早失败。
我确实找到了一个解决方法,它依赖于一个嵌入式函数。使用这种技术,只有一个始终可访问且在范围内的承诺,并且基于计时器的递归(即,不是基于堆栈的)始终包含在永不放弃的单个承诺中。我在 Jaromanda 回答之前将其放在一起,所以我无法确认他的解决方案是否有效。
async function myConnect()
{
return new Promise((resolve, reject) => {
function innerConnect()
{
let mysocket = socketIOClient(url);
mysocket.emit('clientconnect', args, createTimeoutCallback((resp) => {
if (!(resp instanceof TimeoutError)) {
// SUCCESS
doSomething();
resolve();
}
// We timed out, try again
else {
mysocket.close();
setTimeout(innerConnect, 60*1000);
}
}));
}
innerConnect();
});
}