首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的“可塑性”功能超时?

为什么我的“可塑性”功能超时?
EN

Stack Overflow用户
提问于 2020-05-03 17:40:22
回答 2查看 38关注 0票数 1

我一直在搞砸取消承诺的想法,这是一种使用高阶函数的透明方式。我想出了这个:

代码语言:javascript
复制
export const fnGetter = state => fn => (...args) => {
  if (!state.canceled) return fn(...args)
  return Promise.resolve()
}

export const cancelable = (promise, state = {}) => {
  const getFn = fnGetter(state)

  return {
    then: fn => cancelable(promise.then(getFn(fn)), state),
    catch: fn => cancelable(promise.catch(getFn(fn)), state),
    cancel: () => {
      state.canceled = true
    }
  }
}

export const withCancel = promiseReturningFn => (...args) =>
  cancelable(promiseReturningFn(...args))

下面是一些单元测试,在这些测试中,我正在验证我想要的行为。

代码语言:javascript
复制
const delay = withCancel(ms => new Promise(run => setTimeout(run, ms)))

test('works like normal promise when not canceled', async () => {
  const first = jest.fn()
  const second = jest.fn()

  await delay(1000).then(first).then(second)

  expect(first).toHaveBeenCalledTimes(1)
  expect(second).toHaveBeenCalledTimes(1)
})

test('when ignored, does not call callbacks', async () => {
  const first = jest.fn()
  const second = jest.fn()

  const promise = delay(1000).then(first).then(second)
  promise.cancel()

  await promise

  expect(first).not.toHaveBeenCalled()
  expect(second).not.toHaveBeenCalled()
})

我不知道为什么第一个测试会通过,但是在第二个单元测试中调用.cancel()会导致超时。

编辑

我认为这与await在幕后处理then方法的方式有关。我现在只需要帮助。我希望它与异步等待兼容。下面是一个不依赖await的过载版本。

代码语言:javascript
复制
test('when ignored, does not call callbacks', async () => {
  const first = jest.fn()
  const second = jest.fn()

  const promise = delay(1000).then(first).then(second)
  promise.cancel()

  setTimeout(() => {
    expect(first).not.toHaveBeenCalled()
    expect(second).not.toHaveBeenCalled()
  }, 2000)
})
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-03 21:55:31

一个问题是then should take two parameters to deal with rejections

至于为什么会超时:您使用的是await promise,但是await使用的是then,而您的promise被取消了,因此它从不调用回调。取消的承诺应该调用onreject回调,然后您的fnGetter应该忽略该取消错误,只对那些实际上期望您取消的回调忽略该取消错误。

票数 1
EN

Stack Overflow用户

发布于 2020-05-03 19:22:44

我想我知道发生了什么。从阅读中看,await只需要后续的代码,将其封装到一个函数中,然后将该函数传递到正在等待的任何东西的then方法中。如果是这样的话,那么我的代码就正常工作了,expect语句永远不会运行,因为我的承诺(等待中的承诺)被取消了。这就是为什么使用setTimeout运行测试的原因。

下面是我所指的功能的一个基本示例。

代码语言:javascript
复制
const func = async () => {
  await { then: () => console.log("test") }
  console.log("after")
}

上面的代码打印"test",从不打印"after",因为console.log("after")被包装在函数中并传递给对象的then方法,后者从不调用它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61578973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档