首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >笑话:等待对setImmediate和useFakeTimers对新的承诺(SetImmediate)

笑话:等待对setImmediate和useFakeTimers对新的承诺(SetImmediate)
EN

Stack Overflow用户
提问于 2020-06-17 00:40:35
回答 1查看 1K关注 0票数 4

下面是TypeScript中的Jest测试。我想知道为什么需要setImmediate()。

第一个例子是一个有效的测试。下面是我尝试过的各种不起作用的事情。我不明白发生了什么事。pubsub.publish的签名是:(method) PubSub.publish(triggerName: string, payload: any): Promise<void>

代码语言:javascript
复制
  test.only('subscriptions', async () => {
    const document = parse(`
      subscription {
        create 
      }
    `)

    const sub = <AsyncIterator<ExecutionResult>>await subscribe(schema, document);

    expect(sub.next).toBeDefined()

    // setInterval and process.nextTick also work here:
    setImmediate(() => pubsub.publish('CREATE_ONE', { create: "FLUM!" }))  // this works


    const { value: { errors, data } } = await sub.next()

    expect(errors).toBeUndefined()
    expect(data).toBeDefined()
    expect(data.create).toBe('FLUM!')
  }, 10000)

所以这些是我尝试过的其他事情,一些是在研究了类似问题的答案之后。在测试中出现超时异常时,所有这些尝试都失败:

代码语言:javascript
复制
  test.only('subscriptions', async () => {
  // attempt #1: jest.useFakeTimers()

    const document = parse(`
      subscription {
        create 
      }
    `)

    const sub = <AsyncIterator<ExecutionResult>>await subscribe(schema, document);

    expect(sub.next).toBeDefined()

    // #1, cont: 
    // pubsub.publish('CREATE_ONE', { create: "FLUM!" })
    // or...
    // await pubsub.publish('CREATE_ONE', { create: "FLUM!" })
    // this works, though, like in previous test, but with fake timers:
    // setImmediate(() => pubsub.publish('CREATE_ONE', { create: "FLUM!" }))


    // attempt #2:
    // await pubsub.publish('CREATE_ONE', { create: "FLUM!" })

    // attempt #3:
    // pubsub.publish('CREATE_ONE', { create: "FLUM!" })
    // await new Promise(setImmediate)

    // attempt #3a (variant):
    // await new Promise((resolve) => setImmediate(resolve));

    const { value: { errors, data } } = await sub.next()

    expect(errors).toBeUndefined()
    expect(data).toBeDefined()
    expect(data.create).toBe('FLUM!')
  }, 10000)

据我所知,setImmediate将一个函数放在事件循环中,在任何挂起的I/O事件之后立即执行。我不知道为什么需要它,因为pubsub.publish()返回一个承诺,这个承诺可以用一个等待来处理,但是在这种情况下会发生的情况是,下一行等待sub.next()永远不会被调用。

我的想法是,在pubsub.publish()中有一个pubsub.publish调用,setImmediate等待任何挂起的setInterval事件完成(我对此的理解是模糊的)。尝试3和3a是我在其他地方找到的机制,但在这种情况下它们似乎不起作用。

问题是:为什么这个测试需要setImmediate通过?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-27 17:09:34

因此,我的困惑是由于setImmediate做了什么和不做什么。这就是正在发生的事情:

代码语言:javascript
复制
    // setInterval and process.nextTick also work here:
    setImmediate(() => pubsub.publish('CREATE_ONE', { create: "FLUM!" })) 
    const { value: { errors, data } } = await sub.next()

如果没有setImmediate(),则在调用sub.next()之前发送发布事件,因此不会捕获它。您可能认为setImmediate (或process.nextTick)会导致立即执行发布函数,但不会。相反,setImmediate延迟发布调用的时间足够长,足以让sub.next()执行。

现在,我将对setImmediate和process.nextTick的实际工作方式做一些补读。

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

https://stackoverflow.com/questions/62419700

复制
相关文章

相似问题

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