]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(asyncComponent): add `onError` option for defineAsyncComponent
authorEvan You <yyx990803@gmail.com>
Tue, 7 Apr 2020 18:34:42 +0000 (14:34 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 7 Apr 2020 18:34:42 +0000 (14:34 -0400)
BREAKING CHANGE: `retryWhen` and `maxRetries` options for
`defineAsyncComponent` has been replaced by the more flexible `onError`
option, per https://github.com/vuejs/rfcs/pull/148

packages/runtime-core/__tests__/apiAsyncComponent.spec.ts
packages/runtime-core/src/apiAsyncComponent.ts

index fb989296bc15f98ca697042d5f86d6326d24a388..5c3f6a6b85e17153d64aa30f74b1a94c69020a29 100644 (file)
@@ -488,7 +488,13 @@ describe('api: defineAsyncComponent', () => {
           reject = _reject
         })
       },
-      retryWhen: error => error.message.match(/foo/)
+      onError(error, retry, fail) {
+        if (error.message.match(/foo/)) {
+          retry()
+        } else {
+          fail()
+        }
+      }
     })
 
     const root = nodeOps.createElement('div')
@@ -526,7 +532,13 @@ describe('api: defineAsyncComponent', () => {
           reject = _reject
         })
       },
-      retryWhen: error => error.message.match(/bar/)
+      onError(error, retry, fail) {
+        if (error.message.match(/bar/)) {
+          retry()
+        } else {
+          fail()
+        }
+      }
     })
 
     const root = nodeOps.createElement('div')
@@ -549,7 +561,7 @@ describe('api: defineAsyncComponent', () => {
     expect(serializeInner(root)).toBe('<!---->')
   })
 
-  test('retry (fail w/ maxRetries)', async () => {
+  test('retry (fail w/ max retry attempts)', async () => {
     let loaderCallCount = 0
     let reject: (e: Error) => void
 
@@ -560,8 +572,13 @@ describe('api: defineAsyncComponent', () => {
           reject = _reject
         })
       },
-      retryWhen: error => error.message.match(/foo/),
-      maxRetries: 1
+      onError(error, retry, fail, attempts) {
+        if (error.message.match(/foo/) && attempts <= 1) {
+          retry()
+        } else {
+          fail()
+        }
+      }
     })
 
     const root = nodeOps.createElement('div')
index bc18e542f6cfbc59331bef2791e49bb8109ccf9c..7f65f3b47b2540bd03adaa72552848cfee23ef93 100644 (file)
@@ -5,7 +5,7 @@ import {
   ComponentInternalInstance,
   isInSSRComponentSetup
 } from './component'
-import { isFunction, isObject, NO } from '@vue/shared'
+import { isFunction, isObject } from '@vue/shared'
 import { ComponentPublicInstance } from './componentProxy'
 import { createVNode } from './vnode'
 import { defineComponent } from './apiDefineComponent'
@@ -27,9 +27,13 @@ export interface AsyncComponentOptions<T = any> {
   errorComponent?: PublicAPIComponent
   delay?: number
   timeout?: number
-  retryWhen?: (error: Error) => any
-  maxRetries?: number
   suspensible?: boolean
+  onError?: (
+    error: Error,
+    retry: () => void,
+    fail: () => void,
+    attempts: number
+  ) => any
 }
 
 export function defineAsyncComponent<
@@ -45,16 +49,15 @@ export function defineAsyncComponent<
     errorComponent: errorComponent,
     delay = 200,
     timeout, // undefined = never times out
-    retryWhen = NO,
-    maxRetries = 3,
-    suspensible = true
+    suspensible = true,
+    onError: userOnError
   } = source
 
   let pendingRequest: Promise<Component> | null = null
   let resolvedComp: Component | undefined
 
   let retries = 0
-  const retry = (error?: unknown) => {
+  const retry = () => {
     retries++
     pendingRequest = null
     return load()
@@ -67,8 +70,12 @@ export function defineAsyncComponent<
       (thisRequest = pendingRequest = loader()
         .catch(err => {
           err = err instanceof Error ? err : new Error(String(err))
-          if (retryWhen(err) && retries < maxRetries) {
-            return retry(err)
+          if (userOnError) {
+            return new Promise((resolve, reject) => {
+              const userRetry = () => resolve(retry())
+              const userFail = () => reject(err)
+              userOnError(err, userRetry, userFail, retries + 1)
+            })
           } else {
             throw err
           }