全局响应延迟

延迟应用中的所有响应。

虽然你可以使用 delay() API 控制单个响应的响应时间(即延迟),但有时你希望对所有模拟响应一致地应用延迟。你可以使用 MSW 以几种方式执行此操作。

¥While you can control the response time (i.e. delay) of individual responses using the delay() API, sometimes you want to apply a delay consistently to all mocked responses. There are a couple of ways you can do that with MSW.

选项 1:延迟直通处理程序

¥Option 1: A delay passthrough handler

你定义的请求处理程序按顺序执行,这意味着单个拦截的请求可以执行多个请求处理程序(直到有一个返回模拟响应)。

¥The request handlers you define are executed in order, which means that a single intercepted request can execute multiple request handlers (until there’s one that returns a mocked response).

你可以利用该执行顺序并引入一个直通请求处理程序,该处理程序匹配所有传出的请求并在其响应解析器中添加延迟,而无需返回模拟响应。

¥You can take advantage of that execution order and introduce a passthrough request handler that matches all outgoing requests and adds a delay in its response resolver without returning a mocked response.

import { http, delay, HttpResponse } from 'msw'
 
export const handlers = [
  http.all('*', async () => {
    await delay(1000)
  }),
  http.get('/user', () => {
    return HttpResponse.json({ id: 'abc-123' })
  }),
  http.post('/cart/:cartId', () => {
    return new HttpResponse(null, { status: 201 })
  }),
]

在上面的示例中,GET /userPOST /cart/:cartId 请求都将匹配 http.all('*') 请求处理程序,这将延迟它们的最终解析 1000 毫秒。

¥In the example above, both GET /user and POST /cart/:cartId requests will match the http.all('*') request handler, which will delay their eventual resolution by 1000ms.

此选项为你提供了跨所有请求处理程序的一致延迟,但使得更难选择退出特定处理程序的此行为(你必须将它们放在全匹配的 http.all('*') 之前)。

¥This option provides you with a consistent delay across all request handlers but makes it harder to opt-out from this behavior for specific handlers (you’d have to put those before the all-matching http.all('*')).

选项 2:高阶响应解析器

¥Option 2: Higher-order response resolver

你可以创建一个高阶响应解析器,它封装了延迟逻辑,同时让你可以灵活地选择延迟哪些响应。

¥You can create a higher-order response resolver that encapsulates the delay logic while giving you the flexibility over which responses to delay.

// withDelay.ts
import { delay, HttpResponseResolver } from 'msw'
 
export async function withDelay(resolver: HttpResponseResolver): HttpResponseResolver {
  return async (...args) => {
    await delay(1000)
    return resolver(...args)
  }
}

你可以根据需要设计 withDelay() 函数。例如,你可以将其作为参数公开给 withDelay() 函数,以供每个单独的请求处理程序指定,而不是对延迟时间进行硬编码。

¥You can design the withDelay() function as you wish. For example, instead of hard-coding the delay duration, you can expose it as an argument to the withDelay() function for each individual request handler to specify.

// handlers.ts
import { http, HttpResponse } from 'msw'
import { withDelay } from './withDelay'
 
export const handlers = [
  http.get('/user', withDelay(({ request }) => {
    return HttpResponse.json({ id: 'abc-123' })
  }),
  http.post('/cart/:cartId', withDelay(({ request }) => {
    return new HttpResponse(null, { status: 201 })
  }),
  http.get('/products', () => {
    return HttpResponse.json([1, 2, 3])
  })
]

在上面的示例中,GET /userPOST /cart/:cartId 请求将延迟 1000 毫秒,因为它们的响应解析器封装在 withDelay() 高阶解析器中。请注意,GET /products 请求不会有任何延迟。

¥In the example above, the GET /user and POST /cart/:cartId requests will be delayed by 1000ms because their response resolvers are wrapped in the withDelay() higher-order resolver. Note that the GET /products request will no have any delay, respectively.

此选项使你可以更好地控制要延迟的响应,同时将延迟逻辑封装在高阶响应解析器中以保持一致性。

¥This option gives you more control over which responses to delay while encapsulating the delay logic within the higher-order response resolver for consistency.

了解有关创建高阶响应解析器的更多信息:

¥Learn more about creating higher-order response resolvers:

Higher order resolver

Perform an additional request outside of the interception algorithm.