typescript 如何承诺,当异步/同步回调数组和超时同时运行时,对它们进行竞争

pod7payv  于 2022-11-18  发布在  TypeScript
关注(0)|答案(2)|浏览(126)

在关闭Web应用程序之前,我有一组可能在不同持续时间运行的回调。我还有一个超时,如果它超过超时持续时间,我也会关闭应用程序。这样做的原因是为了防止回调在超过超时持续时间时阻止关闭Web应用程序。
以下是我目前的解决方案:

public close() {
      const callbacks = this.onBeforeCloseCallbacks.map((cb) => new Promise(res => res(cb())));
      const timeout = new Promise((res) => setTimeout(res, TIMEOUT_DURATION));
      await Promise.race([Promise.all(callbacks), timeout]).then((value) => {
        // Currently returns Promise.all(callbacks) right away
        console.log(value)
      });
      await this.pluginEngine.close();
    }
  }

这些是我的测试

it('Should still close the plugin when timing out', async () => {
  // Arrange
  const cleanupMock = jest.fn();
  const cb1 = jest.fn().mockReturnValue(async () => new Promise(resolve => setTimeout(() => resolve(console.log('cb1')), 3000)));
  const cleanupMock2 = jest.fn();
  const cb2 = jest.fn().mockReturnValue(async () => new Promise(resolve => setTimeout(() => resolve(console.log('cb2')), 11000)));
  const placementCloseService = new PlacementCloseService(integrationMock, pluginInterface);

  // Act
  // onBeforeClose is registering callbacks that needs to be run before close
  placementCloseService.onBeforeClose(cb1);
  placementCloseService.onBeforeClose(cb2);
  await placementCloseService.close();

  // Assert
  expect(cleanupMock).toBeCalled();
  expect(cleanupMock2).not.toBeCalled();
  expect(pluginInterface.context.close).toBeCalled();
});

我目前的解决方案是返回Promise.all(callbacks),即使它还没有调用预期的回调来运行。我期望发生的是它通过我的timeout,因为它的计时器为4000,而最后一个closeCallback的计时器为5000。
我做错了什么?

vuv7lop3

vuv7lop31#

您的closeCallbacks不是异步的,您需要它们返回一个promise

const closeCallbacks = [
  // for sample purposes. i assigned timeouts to mock that it takes longer to run these callbacks then my timeout duration
  async () => new Promise(resolve => setTimeout(() => resolve(console.log('cb1')), 3000)),
  async () => new Promise(resolve => setTimeout(() => resolve(console.log('cb2')), 5000)),
];
yhxst69z

yhxst69z2#

这将创建名为async的参数,而不是异步函数

(async) => {}

timeout函数从不调用res参数

const wait = (cb, time) => new Promise(r => { cb(); r() }, time)

const closeCallbacks = [
  () => wait(() => console.log('cb1'), 3000),
  () => wait(() => console.log('cb2'), 5000)
];

const timeout = new Promise((res) => setTimeout(() => console.log('timeout'); res(), 4000));

相关问题