【问题标题】:Promise with setTimeout用 setTimeout 承诺
【发布时间】:2020-02-07 03:45:52
【问题描述】:

我想重写这个函数来解决 Promise,而不是调用回调函数,以试图更好地理解如何使用 Promise。

export const connect = (callback: CallableFunction|void): void => {
    LOG.debug("Connecting to DB at %s", URI);

    connectToMongoDb(URI, opts)
        .then((result) => {
            LOG.debug("Connection established");
            connection = result;

            if (callback) {
                callback();
            }
        })
        .catch((err) => {
            LOG.error("Could not establish connection to %s, retrying...", URI);
            LOG.error(err);
            setTimeout(() => connect(callback), 5000);
        });
};

但是,我似乎无法做到。我已经尝试过天真的做法

export const connect = (): Promise<void> => new Promise((resolve): void => {
    // ...´
        .then((result) => {
            LOG.debug("Connection established");
            connection = result;
            resolve();
        })
    // ...
});

但这在建立连接时无法正确解决。

我做错了什么?如何重写它以正确使用和解决 Promise 而不是使用回调函数?

【问题讨论】:

  • 你是如何使用它的? connect 是否从未解决?
  • 避免使用Promise constructor antipattern!制作一个包装setTimeout 的承诺delay 函数,然后将其与适当的承诺链一起使用。
  • @Federkun 我想调用connect().then(),它仅在connectToMongo 解析时才解析。然而发生的事情是connect 永远不会解决
  • @Bergi 我不确定如何应用您链接到我的示例的建议。我不能简单地返回connectToMongoDb 的承诺,因为这只会将问题转移到调用代码...?
  • 是的,你可以。 return connectToMongoDb(URI, opts).then(…).catch(err =&gt; { …; return delay().then(connect); });.

标签: typescript promise callback settimeout


【解决方案1】:

根据 cmets,我能够重构函数以正确返回仅在建立连接时才解析的 Promise:

const delay = (ms: number): Promise<void> =>
    new Promise((resolve): void => {
        setTimeout(resolve, ms);
    });

export const connect = (): Promise<void> => {
    LOG.info("Connecting to DB at %s", URI);

    return connectToMongoDb(URI, opts)
        .then((result) => {
            LOG.info("Connection to DB established");
            connection = result;
        })
        .catch((err) => {
            LOG.error("Could not establish connection to %s, retrying...", URI);
            LOG.error(err);
            return delay(5000).then(connect);
        });
};

【讨论】:

  • 不要设置一个全局的connection变量,你应该通过return result来履行你的承诺
  • 我改变了那部分毕竟因为猫鼬在内部处理连接池。我实际上不需要返回的连接对象。
猜你喜欢
  • 2016-12-09
  • 2016-04-21
  • 2017-01-25
  • 1970-01-01
  • 2020-07-20
相关资源
最近更新 更多