此 Promise 取消实现是否用于在正确的轨道上减少异步可迭代?

我想为我的库的一种方法启用 Promise 取消。我只对取消异步迭代的承诺感兴趣,因为这些承诺很有可能无限期地挂起。reduce


const reduceAsyncIterable = async (fn, possiblyX0, state, x) => {

  const iter = x[Symbol.asyncIterator]()

  const y0 = isUndefined(possiblyX0) ? (await iter.next()).value : possiblyX0

  if (isUndefined(y0)) {

    throw new TypeError('reduce(...)(x); x cannot be empty')

  }

  let y = await fn(y0, (await iter.next()).value)

  for await (const xi of iter) {

    if (state.cancelled) return // stops async iterating if `cancel` called

    y = await fn(y, xi)

  }

  return y

}


const reduce = (fn, x0) => {

  if (!isFunction(fn)) {

    throw new TypeError('reduce(x, y); x is not a function')

  }

  return x => {

    if (isIterable(x)) return reduceIterable(fn, x0, x)

    if (isAsyncIterable(x)) {

      const state = { cancelled: false, resolve: () => {} }

      const p = new Promise((resolve, reject) => {

        state.resolve = resolve

        reduceAsyncIterable(fn, x0, state, x).then(

          y => state.cancelled || resolve(y)

        ).catch(reject)

      })

      p.cancel = () => { state.cancelled = true; state.resolve() } // shortcircuit the Promise `p` on `cancel` call

      return p

    }

    if (is(Object)(x)) return reduceObject(fn, x0, x)

    throw new TypeError('reduce(...)(x); x invalid')

  }

}

上面的代码似乎有效,但我不禁觉得这里有内存泄漏。特别是,在 和 。如果这些等待语句需要永远(它们可能用于异步迭代器),则可能永远不会返回。从用户的角度来看,这很好,因为在 中发生了短路,因为用户看到的承诺已解决。但从计算机的角度来看,取消此操作的承诺会导致内存泄漏吗?await iter.next()for await (const xi of iter)reduceAsyncIterablereduce


我希望能够在返回的承诺上使用该函数,如下所示:cancel


const myOngoingTaskPromise = reduce(someReducer, null)(myInfiniteAsyncIterable)


myOngoingTaskPromise.cancel() // resolves myOngoingTaskPromise with undefined


myOngoingTaskPromise // Promise { undefined }


噜噜哒
浏览 92回答 1
1回答

有只小跳蛙

我找到了这条路,就像一个秘密武器什么的Promise.race    if (isAsyncIterable(x)) {      const state = { cancel: () => {} }      const cancelToken = new Promise((_, reject) => { state.cancel = reject })      const p = Promise.race([        reduceAsyncIterable(fn, x0, x),        cancelToken,      ])      p.cancel = () => { state.cancel(new Error('cancelled')) }      return p    }无内存泄漏
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript