对于循环,没有得到诺言的适当效力

发布于 2025-01-30 02:33:10 字数 2194 浏览 2 评论 0原文

我正在将项目从JavaScript转换为打字稿,并在失败系统上进行重试时遇到了一些问题。该系统在Vanilla JS上正常工作,但似乎在Typescript上的某个地方失败了。

    var t: number = 500;
    var max: number = 5;

    const rejectDelay = (reason: string): Promise<any> => {
        return new Promise((resolve, reject) => {
            log.warn('Unable to connect to database. Trying again...');
            setTimeout(() => reject.bind(null, reason), t);
        });
    };

    const dbConn = async (): Promise<void> => {
        let conn = await db.pool
            .getConnection()

            .then((message: any) => {
                if (!message.isValid()) {
                    throw message.isValid;
                } else {
                    return message.isValid;
                }
            });
    };

    const connected = (res: string): void => {
        log.info('Connection to database is successful.');
        log.info(`App is running in port ${envs.port} in ${envs.mode} mode.`);
    };

    const notConnected = async (err: any): Promise<void> => {
        log.error('Max attempts exceeded, app will exit...');
        process.exit(1);
    };

    var p: Promise<any> = Promise.resolve();

    for (var i = 0; i < max; i++) {
        console.log(i);
        p = p.catch(dbConn).catch(rejectDelay);
    }

    p = p.then(connected).catch(notConnected);

运行项目后,这是预期的结果:

[info] 2022-05-18 01:13:03: Router users registered...
[info] 2022-05-18 01:13:03: Router utils registered...
0
[warn] 2022-05-18 01:12:59: Unable to connect to database. Trying again...
1
[warn] 2022-05-18 01:12:59: Unable to connect to database. Trying again
2
[warn] 2022-05-18 01:12:59: Unable to connect to database. Trying again
3
[warn] 2022-05-18 01:12:59: Unable to connect to database. Trying again
4
[error] 2022-05-18 01:13:44: Max attempts exceeded, app will exit...

这就是我得到的:

[info] 2022-05-18 01:13:03: Router users registered...
[info] 2022-05-18 01:13:03: Router utils registered...
0
1
2
3
4
[error] 2022-05-18 01:13:44: Max attempts exceeded, app will exit...

有什么建议吗?

I've being converting a project from Javascript to Typescript and encountered some problems when running a retry on fail system. This system works fine on vanilla JS but it seems to fail somewhere on Typescript.

    var t: number = 500;
    var max: number = 5;

    const rejectDelay = (reason: string): Promise<any> => {
        return new Promise((resolve, reject) => {
            log.warn('Unable to connect to database. Trying again...');
            setTimeout(() => reject.bind(null, reason), t);
        });
    };

    const dbConn = async (): Promise<void> => {
        let conn = await db.pool
            .getConnection()

            .then((message: any) => {
                if (!message.isValid()) {
                    throw message.isValid;
                } else {
                    return message.isValid;
                }
            });
    };

    const connected = (res: string): void => {
        log.info('Connection to database is successful.');
        log.info(`App is running in port ${envs.port} in ${envs.mode} mode.`);
    };

    const notConnected = async (err: any): Promise<void> => {
        log.error('Max attempts exceeded, app will exit...');
        process.exit(1);
    };

    var p: Promise<any> = Promise.resolve();

    for (var i = 0; i < max; i++) {
        console.log(i);
        p = p.catch(dbConn).catch(rejectDelay);
    }

    p = p.then(connected).catch(notConnected);

after running the project this is expected result:

[info] 2022-05-18 01:13:03: Router users registered...
[info] 2022-05-18 01:13:03: Router utils registered...
0
[warn] 2022-05-18 01:12:59: Unable to connect to database. Trying again...
1
[warn] 2022-05-18 01:12:59: Unable to connect to database. Trying again
2
[warn] 2022-05-18 01:12:59: Unable to connect to database. Trying again
3
[warn] 2022-05-18 01:12:59: Unable to connect to database. Trying again
4
[error] 2022-05-18 01:13:44: Max attempts exceeded, app will exit...

and this is what I get:

[info] 2022-05-18 01:13:03: Router users registered...
[info] 2022-05-18 01:13:03: Router utils registered...
0
1
2
3
4
[error] 2022-05-18 01:13:44: Max attempts exceeded, app will exit...

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

没企图 2025-02-06 02:33:10

如果您希望它停止在第一个连接上,并且希望它在再次尝试连接失败之前等待超时,则需要其他方法。这是一种方法(请注意,您可能必须修复某些打字稿的内容,因为我是普通的JS开发人员,而不是打字稿):

const t: number = 500;
const max: number = 5;

const rejectDelay = (reason: string): Promise<any> => {
    return new Promise((resolve, reject) => {
        log.warn('Unable to connect to database. Trying again...');
        setTimeout(resolve, t, reason);
    });
};

const dbConn = async (): Promise<void> => {
    const conn = await db.pool.getConnection();
    if (!conn.isValid()) {
        throw message.isValid;
    }
    return conn;
};

const connected = (res: string): void => {
    log.info('Connection to database is successful.');
    log.info(`App is running in port ${envs.port} in ${envs.mode} mode.`);
};

const notConnected = async (err: any): Promise<void> => {
    log.error('Max attempts exceeded, app will exit...');
    process.exit(1);
};

async function getConn() {
    for (let i = 0; i < max; i++) {
        try {
            console.log(i);
            let conn = await dbConn();
            return conn;
        } catch(e) {
            await rejectDelay(e);
        }
    }
    throw new Error("database connection failed, all retries used");
} 

getConn().then(result => {
    connected(result);
}).catch(err => {
    notConnected(err);
});

要尝试自己调试,我添加了一堆调试并进行了操作,以便它运行nodejs中的独立。您可以将其复制到单独的文件并自行运行,并查看其工作原理。我已经制作了dbConn(),使其在前3次失败,然后第四次成功,因此您可以看到它的工作原理:

const t = 500;
const max = 5;

function delay(t, v) {
    return new Promise(resolve => setTimeout(resolve, t, v));
}

// simulate db.pool.getConnection()
// fails first 3 times, succeeds after that
const db = {
    pool: {
        async getConnection() {
            await delay(500);
            ++db.pool.cntr;
            if (db.pool.cntr <= 3) {
                throw new Error("Can't connect to Database");
            } else {
                return { connected: true, isValid: () => true };
            }
        },
        cntr: 0
    }
}

// simulate log.info() and log.error
const log = {
    info(...args) {
        console.log(...args);
    },
    error(...args) {
        console.log(...args);
    },
    warn(...args) {
        console.log(...args);
    }
}

// simulate envs
const envs = {
    port: 3000,
    mode: "development"
}

const rejectDelay = (reason) => {
    return new Promise((resolve, reject) => {
        log.warn('Unable to connect to database. Trying again...');
        setTimeout(resolve, t, reason);
    });
};

const dbConn = async () => {
    const conn = await db.pool.getConnection();
    if (!conn.isValid()) {
        throw message.isValid;
    }
    return conn;
};

const connected = (res) => {
    log.info('Connection to database is successful.');
    log.info(`App is running in port ${envs.port} in ${envs.mode} mode.`);
};

const notConnected = async (err) => {
    log.error('Max attempts exceeded, app will exit...');
    process.exit(1);
};

async function getConn() {
    for (let i = 0; i < max; i++) {
        try {
            console.log(i);
            let conn = await dbConn();
            console.log(i, "after");
            return conn;
        } catch (e) {
            console.log(i, "catch");
            await rejectDelay(e);
            console.log(i, "after rejectDelay");
        }
    }
    throw new Error("database connection failed, all retries used");
}

getConn().then(result => {
    connected(result);
}).catch(err => {
    notConnected(err);
});

If you want it to stop on the first connection and you want it to wait a timeout before trying again upon a connection failure, then you need a different approach. Here's one way to do it (note you may have to fix up some TypeScript stuff as I'm a plain JS developer, not TypeScript):

const t: number = 500;
const max: number = 5;

const rejectDelay = (reason: string): Promise<any> => {
    return new Promise((resolve, reject) => {
        log.warn('Unable to connect to database. Trying again...');
        setTimeout(resolve, t, reason);
    });
};

const dbConn = async (): Promise<void> => {
    const conn = await db.pool.getConnection();
    if (!conn.isValid()) {
        throw message.isValid;
    }
    return conn;
};

const connected = (res: string): void => {
    log.info('Connection to database is successful.');
    log.info(`App is running in port ${envs.port} in ${envs.mode} mode.`);
};

const notConnected = async (err: any): Promise<void> => {
    log.error('Max attempts exceeded, app will exit...');
    process.exit(1);
};

async function getConn() {
    for (let i = 0; i < max; i++) {
        try {
            console.log(i);
            let conn = await dbConn();
            return conn;
        } catch(e) {
            await rejectDelay(e);
        }
    }
    throw new Error("database connection failed, all retries used");
} 

getConn().then(result => {
    connected(result);
}).catch(err => {
    notConnected(err);
});

To attempt to debug this myself, I added a bunch of debugging and made it so it would run stand-alone in nodejs. You can copy this to a separate file and run it by itself and see how it works. I've made dbConn() such that it fails the first 3 times, then succeeds the fourth time so you can see how it works:

const t = 500;
const max = 5;

function delay(t, v) {
    return new Promise(resolve => setTimeout(resolve, t, v));
}

// simulate db.pool.getConnection()
// fails first 3 times, succeeds after that
const db = {
    pool: {
        async getConnection() {
            await delay(500);
            ++db.pool.cntr;
            if (db.pool.cntr <= 3) {
                throw new Error("Can't connect to Database");
            } else {
                return { connected: true, isValid: () => true };
            }
        },
        cntr: 0
    }
}

// simulate log.info() and log.error
const log = {
    info(...args) {
        console.log(...args);
    },
    error(...args) {
        console.log(...args);
    },
    warn(...args) {
        console.log(...args);
    }
}

// simulate envs
const envs = {
    port: 3000,
    mode: "development"
}

const rejectDelay = (reason) => {
    return new Promise((resolve, reject) => {
        log.warn('Unable to connect to database. Trying again...');
        setTimeout(resolve, t, reason);
    });
};

const dbConn = async () => {
    const conn = await db.pool.getConnection();
    if (!conn.isValid()) {
        throw message.isValid;
    }
    return conn;
};

const connected = (res) => {
    log.info('Connection to database is successful.');
    log.info(`App is running in port ${envs.port} in ${envs.mode} mode.`);
};

const notConnected = async (err) => {
    log.error('Max attempts exceeded, app will exit...');
    process.exit(1);
};

async function getConn() {
    for (let i = 0; i < max; i++) {
        try {
            console.log(i);
            let conn = await dbConn();
            console.log(i, "after");
            return conn;
        } catch (e) {
            console.log(i, "catch");
            await rejectDelay(e);
            console.log(i, "after rejectDelay");
        }
    }
    throw new Error("database connection failed, all retries used");
}

getConn().then(result => {
    connected(result);
}).catch(err => {
    notConnected(err);
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文