簡體   English   中英

笑話:await vs setImmediate vs useFakeTimers vs new Promise(setImmediate)

[英]Jest: await vs setImmediate vs useFakeTimers vs new Promise(setImmediate)

以下是 TypeScript 中的 Jest 測試。 我想知道為什么需要 setImmediate() 。

第一個例子是一個有效的測試。 接下來是我嘗試過的各種不起作用的東西。 我不明白發生了什么。 pubsub.publish 的簽名是: (method) PubSub.publish(triggerName: string, payload: any): Promise<void>

  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)

所以這些是我嘗試過的其他事情,有些是在研究了類似問題的答案之后。 所有這些嘗試都失敗,並在測試中出現超時異常:



  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 將 function 放入事件循環中,以便在任何未決的 I/O 事件之后立即執行。 我不確定為什么需要它,因為 pubsub.publish() 返回一個 Promise 可以用await處理,但在這種情況下發生的是下一行, await sub.next()永遠不會被調用。

我的想法是在 pubsub.publish() 中有一個 setInterval 調用,並且 setImmediate 等待任何未決的 setInterval 事件完成(我對此的理解很模糊)。 嘗試 3 和 3a 是我在其他地方找到的用於執行此操作的機制,但在這種情況下它們似乎不起作用。

問題:為什么這個測試需要 setImmediate 才能通過?

所以我的困惑是由於 setImmediate 做什么和不做什么。 這是正在發生的事情:

    // 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)會導致立即執行發布 function,但不是。 相反, setImmediate 將發布調用延遲足夠長的時間以供 sub.next() 執行。

我現在將對 setImmediate 和 process.nextTick 的實際工作方式進行一些補救性閱讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM