我正在尝试使用Node.js中的net.Socket连接到计算机。有时连接正常,我成功,有时连接断开,所以我一直在重试。
我想编写一个reconnect
方法,尝试连接到IP。当它成功时,它会结算,但如果它失败了它应该继续尝试。
const reconnect = function ( connectOpts ) {
return new Promise( resolve => {
connect( connectOpts )
.then( () => {
console.log( "CONNECTED " );
resolve();
} )
.catch( () => {
console.log( "RETRYING" );
connect( connectOpts );
} );
} );
};
const connect = function ( connectOpts ) {
return new Promise( ( resolve, reject ) => {
socket = net.createConnection( connectOpts );
//once I receive the 1st bytes of data, I resolve();
socket.once( "data", () => {
resolve();
} );
socket.once( "error", err => reject( err ) );
} );
};
reconnect({host: localhost, port: 8080})
.then(() => console.log("I made it!"));
问题是,当连接失败时,它只会再次尝试,然后它会爆炸!
如何更改我的代码,以便每次失败时都会重新连接? PS:此功能非常重要异步!
答案 0 :(得分:0)
正如您正确指出的那样,当您尝试从.catch()方法进行连接时,代码会爆炸。
.catch( () => {
console.log( "RETRYING" );
connect( connectOpts );
} );
有两个选项可以解决这个问题
选项1:使用ES6 Generator功能
我最近遇到了类似的问题,我使用生成器函数来解决我的问题。本质上,生成器函数允许您暂停执行,直到异步任务完成。然后,您可以根据异步任务的结果继续执行
参考 - https://eladnava.com/write-synchronous-node-js-code-with-es6-generators/
选项2-使用延期承诺
您可以对此用例使用称为延迟承诺的内容。更多细节 - https://mostafa-samir.github.io/async-recursive-patterns-pt2/
此外,类似的stackoverlow问题在这里 - execute promises recursively nodejs
希望有所帮助!
答案 1 :(得分:0)
试试这个:
const connect = function(connectOpts) {
const connectResolver = (resolve) => {
socket = net.createConnection(connectOpts);
socket.once("data", resolve);
socket.once("error", () =>
// you can try setTimeout() here with specific retry in milliseconds here
// say like setTimeout(() => connectResolver(resolve), 200);
// instead of immediate retry in the end of every event loop
// up to you
setImmediate(() => connectResolver(resolve)));
}
return new Promise(connectResolver);
};
connect({
host: localhost,
port: 8080
})
.then(() => console.log("I made it!"));
答案 2 :(得分:0)
检查代码,我发现了这个。
resolve
或reject
。然后UnhandledPromiseRejectionWarning
可能会发生。 然后让我们在reconnect
处理程序中调用.catch
。解决后,通过调用resolve()
来解决Promise问题。
const reconnect = function ( connectOpts ) {
return new Promise( resolve => {
connect( connectOpts )
.then( () => {
console.log( "CONNECTED " );
resolve();
} )
.catch( () => {
console.log( "RETRYING" );
// connect( connectOpts );
return reconnect( connectOpts )
.then(() => {
resolve();
});
} );
} );
};
答案 3 :(得分:0)
在阅读完所有其他解决方案之后,我最终选择了这个:
const reconnect = async function ( connectOpts ) {
let done = false;
while ( !done ) {
done = await connect( connectOpts )
.then( () => true )
.catch( () => false );
}
};
const connect = function ( connectOpts ) {
return new Promise( ( resolve, reject ) => {
socket = net.createConnection( connectOpts );
//once I receive the 1st bytes of data, I resolve();
socket.once( "data", () => {
resolve();
} );
socket.once( "error", err => reject( err ) );
} );
};
reconnect({host: localhost, port: 8080})
.then(() => console.log("I made it!"));
我的解决方案解决了所有这些问题。
不,不是。它会是任何其他语言,但是在这里,因为我使用await
运算符,我实际上允许Node继续执行循环。就像一个承诺。