<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      lodash已死?Radash庫方法介紹及源碼解析 —— 異步方法篇

      寫在前面

      tips:點贊 + 收藏 = 學會!

      • 我們前面已經介紹了 radash 的相關信息和所有 Array 相關方法,詳情可前往主頁查看。
      • 本篇我們繼續介紹radash中異步相關的方法。
      • 所有方法分享完畢后,后續作者也會整理出 Radash 庫所有方法的使用目錄,包括文章說明腦圖說明
        • 因為方法較多,后續將專門發布一篇總結文檔,方便大家查閱使用。
        • 所有方法的思維導圖說明后續也會上傳至 github 和 gitee,有需要的可以訪問下載。

      all:同時執行多個異步操作

      1. 使用說明
        1. 功能描述: 類似于 Promise.allPromise.allSettled,等待一個由多個 Promise 組成的對象或數組中的所有 Promise 都完成(或者其中一個失敗)。執行的所有錯誤和拋出的錯誤都會收集在 AggregateError 中。
        2. 參數:promise對象/promise數組
        3. 返回值:所有 promise 執行后的結果數組或對象
      2. 使用代碼示例
        import { all } from 'radash'
        
        // 傳入promise數組
        const [user] = await all([
          api.users.create(...),
          s3.buckets.create(...),
          slack.customerSuccessChannel.sendMessage(...)
        ])
        
        // 傳入對象
        const { user } = await all({
          user: api.users.create(...),
          bucket: s3.buckets.create(...),
          message: slack.customerSuccessChannel.sendMessage(...)
        })
        
      3. 源碼解析
        // 定義一個泛型異步函數 `all`。
        export async function all<
          // 泛型約束 `T` 可以是一個 `Promise` 數組或一個 `Promise` 對象。
          T extends Record<string, Promise<any>> | Promise<any>[]
        >(promises: T) {
          // 根據 `promises` 是數組還是對象,將其轉換成一個統一格式的數組 `entries`。
          const entries = isArray(promises)
            ? promises.map(p => [null, p] as [null, Promise<any>])
            : Object.entries(promises)
        
          // 使用 `Promise.all` 等待所有 `Promise` 完成,并處理每個 `Promise` 的結果和異常。
          const results = await Promise.all(
            entries.map(([key, value]) =>
              value
                .then(result => ({ result, exc: null, key })) // 如果成功,記錄結果。
                .catch(exc => ({ result: null, exc, key })) // 如果失敗,記錄異常。
            )
          )
        
          // 篩選出所有出現異常的結果。
          const exceptions = results.filter(r => r.exc)
          // 如果有異常,拋出一個 `AggregateError`,包含所有異常。
          if (exceptions.length > 0) {
            throw new AggregateError(exceptions.map(e => e.exc))
          }
        
          // 如果輸入的 `promises` 是數組,返回一個包含所有結果的數組。
          if (isArray(promises)) {
            return results.map(r => r.result) as T extends Promise<any>[]
              ? PromiseValues<T>
              : unknown
          }
        
          // 如果輸入的 `promises` 是對象,將結果組合成一個新對象并返回。
          return results.reduce(
            (acc, item) => ({
              ...acc,
              [item.key!]: item.result // 使用斷言 `item.key!`,因為我們知道 `key` 不會是 `null`。
            }),
            {} as { [K in keyof T]: Awaited<T[K]> } // 返回類型是一個對象,其鍵類型為 `T` 的鍵,值類型為 `T` 中 `Promise` 解析后的類型。
          )
        }
        
        • 方法流程說明:
          1. 將輸入的 promises 轉換為一個統一格式的 entries 數組,無論它是一個 Promise 數組還是一個 Promise 對象。
          2. 對于每個 entry,創建一個新的 Promise 來處理成功和失敗的情況,并使用 Promise.all 等待所有這些新 Promise 完成。
          3. 如果所有 Promise 都成功解析,根據 promises 是數組還是對象,返回一個包含所有結果的數組或對象。
          4. 如果有一個或多個 Promise 失敗,則拋出一個 AggregateError,其中包含所有失敗的 Promise 的異常。

      defer:在異步流程中添加清理或錯誤處理邏輯

      1. 使用說明
        1. 功能描述:用來執行一個異步函數,同時提供注冊回調的機制,在異步函數執行完成后執行特定回調操作。
        2. 參數:異步函數。
        3. 返回值:異步函數成功執行時,返回其響應結果,否則重新拋出錯誤。
      2. 使用代碼示例
        import { defer } from 'radash'
        
        await defer(async (cleanup) => {
          const buildDir = await createBuildDir()
        
          cleanup(() => fs.unlink(buildDir))
        
          await build()
        })
        
        await defer(async (register) => {
          const org = await api.org.create()
          register(async () => api.org.delete(org.id), { rethrow: true })
        
          const user = await api.user.create()
          register(async () => api.users.delete(user.id), { rethrow: true })
        
          await executeTest(org, user)
        })
        
      3. 源碼解析
        // 定義一個異步泛型函數 `defer`。
        export const defer = async <TResponse>(
          // `func` 是一個接受注冊函數 `register` 的異步函數。
          func: (
            register: (
              // `register` 允許 `func` 注冊一個回調函數 `fn`,該函數在 `func` 執行完成后調用。
              // 可以通過 `options` 指定是否在回調函數中重新拋出錯誤。
              fn: (error?: any) => any,
              options?: { rethrow?: boolean }
            ) => void
          ) => Promise<TResponse>
        ): Promise<TResponse> => {
          // 初始化一個用于存放回調函數及其選項的數組 `callbacks`。
          const callbacks: {
            fn: (error?: any) => any
            rethrow: boolean
          }[] = []
        
          // 實現注冊函數 `register`,它將回調函數及其選項添加到 `callbacks` 數組。
          const register = (
            fn: (error?: any) => any,
            options?: { rethrow?: boolean }
          ) =>
            callbacks.push({
              fn,
              rethrow: options?.rethrow ?? false
            })
        
          // 調用 `tryit` 函數執行 `func`,并傳入 `register`。
          // `tryit` 函數不在提供的代碼片段中,但我們可以假設它是一個錯誤處理函數,返回一個包含錯誤和響應的元組。
          const [err, response] = await tryit(func)(register)
        
          // 遍歷 `callbacks` 數組,依次執行每個回調函數。
          for (const { fn, rethrow } of callbacks) {
            // 使用 `tryit` 函數調用回調,以捕獲并處理任何拋出的錯誤。
            const [rethrown] = await tryit(fn)(err)
            // 如果回調函數中有錯誤被重新拋出,并且 `rethrow` 選項為 `true`,則重新拋出該錯誤。
            if (rethrown && rethrow) throw rethrown
          }
        
          // 如果 `func` 執行時有錯誤產生,重新拋出該錯誤。
          if (err) throw err
          // 如果 `func` 執行成功,返回響應結果。
          return response
        }
        
        • 方法流程說明:
          1. 定義一個 callbacks 數組來存儲注冊的回調函數及其選項。
          2. 實現 register 函數,該函數允許 func 注冊回調函數和選項。
          3. 調用外部提供的(但在代碼片段中未定義)tryit 函數執行 func,并傳遞 register 函數給 func
          4. 等待 func 完成執行,獲取可能的錯誤 err 和響應 response
          5. 依次執行 callbacks 數組中的回調函數,處理可能的錯誤。
          6. 如果任何一個回調函數中出現需要重新拋出的錯誤,并且其 rethrow 選項為 true,則重新拋出該錯誤。
          7. 如果 func 執行時產生了錯誤,重新拋出該錯誤。
          8. 如果 func 成功執行,返回其響應結果。

      guard:執行一個函數,并提供錯誤處理的能力

      1. 使用說明
        1. 功能描述:guard 函數可以用來為函數調用提供額外的錯誤處理邏輯,特別是當你希望根據錯誤類型選擇性地處理錯誤時。
        2. 參數:目標函數、指定錯誤對象得函數(可選)。
        3. 返回值:拋出原始或返回undefined。
      2. 使用代碼示例
        import { guard } from 'radash'
        
        const users = (await guard(fetchUsers)) ?? []
        
        const isInvalidUserError = (err: any) => err.code === 'INVALID_ID'
        const user = (await guard(fetchUser, isInvalidUserError)) ?? DEFAULT_USER
        
      3. 源碼解析
        // 定義一個泛型函數 `guard`。
        export const guard = <TFunction extends () => any>(
          // 參數 `func` 是一個無參數的函數,它可能返回任何類型的值,包括 `Promise`。
          func: TFunction,
          // 可選參數 `shouldGuard` 是一個函數,它接受一個錯誤對象 `err`,
          // 并返回一個布爾值,指示是否應該 "guard" 這個錯誤。
          shouldGuard?: (err: any) => boolean
        // 函數的返回類型依賴于 `func` 的返回類型。如果 `func` 返回一個 `Promise`,
        // 則 `guard` 返回一個 `Promise`,該 `Promise` 解析為 `func` 的返回值或 `undefined`。
        // 如果 `func` 不返回 `Promise`,則 `guard` 返回 `func` 的返回值或 `undefined`。
        ): ReturnType<TFunction> extends Promise<any>
          ? Promise<Awaited<ReturnType<TFunction>> | undefined>
          : ReturnType<TFunction> | undefined => {
          // 定義一個內部函數 `_guard`,它接受一個錯誤對象 `err`。
          const _guard = (err: any) => {
            // 如果提供了 `shouldGuard` 函數并且該函數返回 `false`,
            // 表示不應該 "guard" 這個錯誤,則重新拋出該錯誤。
            if (shouldGuard && !shouldGuard(err)) throw err
            // 否則,返回 `undefined`。
            return undefined as any
          }
        
          // 定義一個類型守衛函數 `isPromise`,它檢查一個值是否為 `Promise`。
          const isPromise = (result: any): result is Promise<any> =>
            result instanceof Promise
        
          try {
            // 嘗試執行 `func` 并獲取結果。
            const result = func()
            // 如果 `result` 是一個 `Promise`,使用 `catch` 方法應用 `_guard` 函數。
            // 否則,直接返回 `result`。
            return isPromise(result) ? result.catch(_guard) : result
          } catch (err) {
            // 如果在執行 `func` 時拋出錯誤,使用 `_guard` 函數處理該錯誤。
            return _guard(err)
          }
        }
        
        • 方法流程說明:
          1. 嘗試執行 func 函數并捕獲任何拋出的錯誤。
          2. 如果 func 執行成功并返回一個 Promise,那么使用 catch 方法捕獲該 Promise 可能拋出的錯誤,并應用 _guard 函數。
          3. 如果 func 執行成功并沒有返回 Promise,那么直接返回結果。
          4. 如果 func 拋出錯誤,應用 _guard 函數來決定是否重新拋出錯誤或返回 undefined
          5. 如果提供了 shouldGuard 函數,它將用來判斷是否應該 "guard"(捕獲并返回 undefined)錯誤。如果 shouldGuard 函數返回 false,則拋出原始錯誤;如果返回 true 或未提供 shouldGuard 函數,則返回 undefined

      map:對一個數組中的每個元素執行一個異步映射函數

      1. 使用說明
        1. 功能描述:它用于對一個數組中的每個元素執行一個異步映射函數,并返回一個包含所有映射結果的新數組。這個函數是 Array.prototype.map 方法的異步版本。
        2. 參數:數組,異步函數。
        3. 返回值:映射后的新數組。
      2. 使用代碼示例
        import { map } from 'radash'
        
        const userIds = [1, 2, 3, 4]
        
        const users = await map(userIds, async (userId) => {
          return await api.users.find(userId)
        })
        
      3. 源碼解析
        // 定義一個異步函數 `map`。
        export const map = async <T, K>(
          // 第一個參數 `array` 是一個具有只讀屬性的泛型數組。
          array: readonly T[],
          // 第二個參數 `asyncMapFunc` 是一個異步映射函數,它接受一個數組元素和它的索引,
          // 返回一個 `Promise`,該 `Promise` 解析為新類型 `K` 的值。
          asyncMapFunc: (item: T, index: number) => Promise<K>
        ): Promise<K[]> => {
          // 如果傳入的數組 `array` 不存在,則返回一個空數組。
          if (!array) return []
          // 初始化一個空數組 `result`,用于存放映射后的新值。
          let result = []
          // 初始化一個索引計數器 `index`。
          let index = 0
          // 使用 `for...of` 循環遍歷數組 `array` 的每個元素。
          for (const value of array) {
            // 對每個元素調用 `asyncMapFunc` 映射函數,并等待其 `Promise` 解析。
            const newValue = await asyncMapFunc(value, index++)
            // 將解析后的新值添加到 `result` 數組中。
            result.push(newValue)
          }
          // 循環完成后,返回包含所有新值的數組 `result`。
          return result
        }
        
        • 方法流程說明:
          1. 檢查 array 是否存在。如果不存在,返回一個空數組。
          2. 初始化一個空數組 result 用于存儲映射結果,以及一個索引計數器 index
          3. 遍歷 array 中的每個元素。
          4. 對于每個元素,調用異步映射函數 asyncMapFunc 并等待 Promise 解析。
          5. 將異步映射函數解析后的結果添加到 result 數組中。
          6. 在遍歷完所有元素之后,返回包含所有映射結果的 result 數組。

      parallel:并行地處理數組中的元素,并對每個元素執行一個異步函數

      1. 使用說明
        1. 功能描述:這個函數會限制同時進行的異步操作的數量,以避免同時啟動過多的異步任務。
        2. 參數:限制數量(number)、需要被異步處理的元素數組、轉換函數(將數組中的每個元素轉換為一個異步操作)。
        3. 返回值:返回一個數組,該數組包含了按原數組順序排序的所有成功的結果。
      2. 使用代碼示例
        // 定義一個異步泛型函數 `parallel`。
        export const parallel = async <T, K>(
          // `limit` 是一個數字,指定了可以同時運行的異步任務的最大數量。
          limit: number,
          // `array` 是一個只讀數組,包含將要被異步處理的元素。
          array: readonly T[],
          // `func` 是一個函數,將數組中的每個元素轉換為一個異步操作(返回 Promise)。
          func: (item: T) => Promise<K>
        ): Promise<K[]> => {
          // 將數組 `array` 轉換為包含元素和它們索引的對象的數組 `work`。
          const work = array.map((item, index) => ({
            index,
            item
          }))
          // 定義一個處理函數 `processor`,它將異步處理 `work` 數組中的元素。
          const processor = async (res: (value: WorkItemResult<K>[]) => void) => {
            const results: WorkItemResult<K>[] = []
            while (true) {
              // 從 `work` 數組的末尾取出一個元素進行處理。
              const next = work.pop()
              // 如果沒有更多元素,調用回調函數 `res` 并傳入結果數組 `results`。
              if (!next) return res(results)
              // 使用 `tryit` 函數執行 `func` 并處理結果或錯誤。
              const [error, result] = await tryit(func)(next.item)
              // 將結果或錯誤添加到 `results` 數組中。
              results.push({
                error,
                result: result as K,
                index: next.index
              })
            }
          }
          // 創建一個 `queues` 數組,它包含了 `limit` 個新的 Promise,每個 Promise 都由 `processor` 函數處理。
          const queues = list(1, limit).map(() => new Promise(processor))
          // 使用 `Promise.all` 等待所有的 `queues` 中的 Promise 完成。
          const itemResults = (await Promise.all(queues)) as WorkItemResult<K>[][]
          // 將所有的結果扁平化并根據索引排序,然后使用 `fork` 函數將結果分為錯誤和成功的結果。
          const [errors, results] = fork(
            sort(itemResults.flat(), r => r.index),
            x => !!x.error
          )
          // 如果有任何錯誤,拋出一個 `AggregateError` 包含所有錯誤。
          if (errors.length > 0) {
            throw new AggregateError(errors.map(error => error.error))
          }
          // 返回一個數組,它包含了按原數組順序排序的所有成功的結果。
          return results.map(r => r.result)
        }
        
      3. 源碼解析
        // 定義一個異步泛型函數 `parallel`。
        export const parallel = async <T, K>(
          // `limit` 是一個數字,指定了可以同時運行的異步任務的最大數量。
          limit: number,
          // `array` 是一個只讀數組,包含將要被異步處理的元素。
          array: readonly T[],
          // `func` 是一個函數,將數組中的每個元素轉換為一個異步操作(返回 Promise)。
          func: (item: T) => Promise<K>
        ): Promise<K[]> => {
          // 將數組 `array` 轉換為包含元素和它們索引的對象的數組 `work`。
          const work = array.map((item, index) => ({
            index,
            item
          }))
          // 定義一個處理函數 `processor`,它將異步處理 `work` 數組中的元素。
          const processor = async (res: (value: WorkItemResult<K>[]) => void) => {
            const results: WorkItemResult<K>[] = []
            while (true) {
              // 從 `work` 數組的末尾取出一個元素進行處理。
              const next = work.pop()
              // 如果沒有更多元素,調用回調函數 `res` 并傳入結果數組 `results`。
              if (!next) return res(results)
              // 使用 `tryit` 函數執行 `func` 并處理結果或錯誤。
              const [error, result] = await tryit(func)(next.item)
              // 將結果或錯誤添加到 `results` 數組中。
              results.push({
                error,
                result: result as K,
                index: next.index
              })
            }
          }
          // 創建一個 `queues` 數組,它包含了 `limit` 個新的 Promise,每個 Promise 都由 `processor` 函數處理。
          const queues = list(1, limit).map(() => new Promise(processor))
          // 使用 `Promise.all` 等待所有的 `queues` 中的 Promise 完成。
          const itemResults = (await Promise.all(queues)) as WorkItemResult<K>[][]
          // 將所有的結果扁平化并根據索引排序,然后使用 `fork` 函數將結果分為錯誤和成功的結果。
          const [errors, results] = fork(
            sort(itemResults.flat(), r => r.index),
            x => !!x.error
          )
          // 如果有任何錯誤,拋出一個 `AggregateError` 包含所有錯誤。
          if (errors.length > 0) {
            throw new AggregateError(errors.map(error => error.error))
          }
          // 返回一個數組,它包含了按原數組順序排序的所有成功的結果。
          return results.map(r => r.result)
        }
        
        • 這段代碼中使用了幾個未定義的函數和類型,如 tryitlistforksort,以及類型 WorkItemResult<K>。我們可以假設這些函數和類型具有以下功能:
          • tryit(func)(item):執行 func(item) 并捕獲任何拋出的錯誤,返回一個包含錯誤和結果的元組。
          • list(1, limit):創建一個包含從 1 到 limit 的數字的數組。
          • fork(array, condition):分割數組 array,根據 condition 函數返回的布爾值將數組分為包含錯誤的元素和成功的元素兩個數組。
          • sort(array, keySelector):根據 keySelector 函數返回的鍵對數組 array 進行排序。
          • WorkItemResult<K>:一個類型,表示工作項的結果,包含可能的 error、成功的 result 以及元素的 index

      reduce:對數組中的每個元素執行一個異步歸約函數

      1. 使用說明
        1. 功能描述:它是 Array.prototype.reduce 方法的異步版本,用于對數組中的每個元素執行一個異步歸約函數,并返回最終的歸約值。
        2. 參數:被歸約處理的元素數組、異步歸約函數。
        3. 返回值:返回最終歸約的值。
      2. 使用代碼示例
        import { reduce } from 'radash'
        
        const userIds = [1, 2, 3, 4]
        
        const users = await reduce(userIds, async (acc, userId) => {
          const user = await api.users.find(userId)
          return {
            ...acc,
            [userId]: user
          }
        }, {})
        
      3. 源碼解析
        // 定義一個異步泛型函數 `reduce`。
        export const reduce = async <T, K>(
          // 第一個參數 `array` 是一個只讀數組,包含將要被歸約處理的元素。
          array: readonly T[],
          // 第二個參數 `asyncReducer` 是一個異步歸約函數,它接受累加值 `acc`、當前元素 `item` 和它的索引 `index`,
          // 并返回一個 `Promise`,該 `Promise` 解析為新的累加值。
          asyncReducer: (acc: K, item: T, index: number) => Promise<K>,
          // 第三個參數 `initValue` 是可選的初始值。
          initValue?: K
        ): Promise<K> => {
          // 檢查初始值是否提供了。
          const initProvided = initValue !== undefined
          // 如果沒有提供初始值且數組為空,則拋出錯誤。
          if (!initProvided && array?.length < 1) {
            throw new Error('Cannot reduce empty array with no init value')
          }
          // 如果提供了初始值,使用整個數組;否則,從數組的第二個元素開始迭代。
          const iter = initProvided ? array : array.slice(1)
          // 初始化累加值 `value`。如果提供了初始值,使用它;否則使用數組的第一個元素。
          let value: any = initProvided ? initValue : array[0]
          // 使用 `for...of` 循環和 `entries` 方法遍歷數組或其子數組。
          for (const [i, item] of iter.entries()) {
            // 對每個元素調用異步歸約函數 `asyncReducer` 并等待其 `Promise` 解析。
            value = await asyncReducer(value, item, i)
          }
          // 循環完成后,返回最終的累加值 `value`。
          return value
        }
        
        • 方法流程說明:
          1. 檢查是否提供了初始值 initValue
          2. 如果沒有提供初始值且數組為空,則拋出錯誤,因為無法從空數組中歸約出一個值。
          3. 確定迭代的數組。如果提供了初始值,則迭代整個數組;如果沒有提供初始值,則從數組的第二個元素開始迭代。
          4. 初始化累加值 value。如果提供了初始值,則使用該初始值;如果沒有提供初始值,則使用數組的第一個元素作為初始累加值。
          5. 遍歷數組,對每個元素調用異步歸約函數 asyncReducer,并等待其返回的 Promise 解析。
          6. 更新累加值 valueasyncReducer 返回的新值。
          7. 在遍歷完所有元素之后,返回最終的累加值。

      retry:反復嘗試執行一個異步操作,直到達到設置上限

      1. 使用說明
        1. 功能描述:用于反復嘗試執行一個異步操作,直到成功或達到重試次數上限。如果操作失敗,可以選擇在重試之間設置延遲或使用退避函數(backoff)來計算延遲時間。
        2. 參數:條件對象options(包含:重復次數、延遲、退避函數)、失敗執行的異步操作函數。
        3. 返回值:可能發揮undefined。
      2. 使用代碼示例
        import { retry } from 'radash'
        
        await retry({}, api.users.list)
        await retry({ times: 10 }, api.users.list)
        await retry({ times: 2, delay: 1000 }, api.users.list)
        
        // exponential backoff
        await retry({ backoff: i => 10**i }, api.users.list)
        
      3. 源碼解析
        // 定義一個異步泛型函數 `retry`。
        export const retry = async <TResponse>(
          // `options` 對象包含重試策略的選項。
          options: {
            times?: number // 重試次數,默認為 3。
            delay?: number | null // 固定延遲時間,如果提供,則在重試之間等待這么多毫秒。
            backoff?: (count: number) => number // 退避函數,可以根據重試次數來計算延遲時間。
          },
          // `func` 是要執行的異步函數,它可能會失敗。
          func: (exit: (err: any) => void) => Promise<TResponse>
        ): Promise<TResponse> => {
          // 從 `options` 中獲取重試次數、固定延遲時間和退避函數。
          const times = options?.times ?? 3
          const delay = options?.delay
          const backoff = options?.backoff ?? null
        
          // 使用 `range` 函數生成一個序列,并遍歷這個序列進行重試。
          for (const i of range(1, times)) {
            // 嘗試執行 `func` 函數,并捕獲可能的錯誤 `err` 和結果 `result`。
            const [err, result] = (await tryit(func)((err: any) => {
              // 如果 `func` 失敗,并使用 `exit` 函數退出,則拋出一個特殊的錯誤對象。
              throw { _exited: err }
            })) as [any, TResponse]
        
            // 如果沒有錯誤,說明 `func` 成功執行,返回結果。
            if (!err) return result
        
            // 如果有特殊的退出錯誤,重新拋出原始錯誤。
            if (err._exited) throw err._exited
        
            // 如果是最后一次重試且仍然失敗,拋出錯誤。
            if (i === times) throw err
        
            // 如果設置了固定延遲時間,使用 `sleep` 函數等待。
            if (delay) await sleep(delay)
        
            // 如果提供了退避函數,根據重試次數計算延遲時間并等待。
            if (backoff) await sleep(backoff(i))
          }
        
          // 如果代碼執行到這里,說明邏輯上不應該到達的代碼路徑。
          // 這是為了滿足 TypeScript 的嚴格模式要求。
          /* istanbul ignore next */
          return undefined as unknown as TResponse
        }
        
        • 方法流程說明:
          1. options 中獲取重試次數、延遲和退避函數。
          2. 遍歷從 1 到重試次數的范圍。
          3. 在每次迭代中,嘗試執行 func 并捕獲可能的錯誤和結果。
          4. 如果 func 成功執行(沒有錯誤),返回結果。
          5. 如果有錯誤,并且是通過 exit 函數顯式退出的,重新拋出原始錯誤。
          6. 如果達到了重試次數上限并且仍然失敗,拋出最后一次的錯誤。
          7. 如果指定了延遲或退避函數,根據相應的策略等待一段時間后再重試。
          8. 如果執行到函數的末尾,返回 undefined 作為占位符,因為邏輯上不應該到達這里。

      sleep:提供一個延時機制

      1. 使用說明
        1. 功能描述:提供一個延時機制,通常用于異步操作中的暫停。
        2. 參數:暫停時間(ms)。
        3. 返回值:返回一個新的Promise。
      2. 使用代碼示例
        import { sleep } from 'radash'
        
        await sleep(2000) // => waits 2 seconds
        
      3. 源碼解析
        // 定義一個名為 `sleep` 的函數。
        export const sleep = (milliseconds: number) => {
          // 返回一個新的 Promise。
          return new Promise(res => 
            // 使用 `setTimeout` 函數設置一個定時器,它在 `milliseconds` 指定的毫秒數后執行。
            setTimeout(
              // 當定時器到時,調用 `res` 函數來解析這個 Promise。
              res,
              // 傳遞給 `setTimeout` 的毫秒數,它決定了延時的長度。
              milliseconds
            )
          )
        }
        
        • 方法流程說明:當你調用 sleep 函數并傳入一個毫秒數時,它會返回一個 Promise。這個 Promise 不會立即解析,而是會等待你指定的時間長度。當時間到了之后,Promise 會被解析,然后你可以在 .then() 方法中繼續執行后續的代碼,或者你可以在 async 函數中使用 await 關鍵字來等待 Promise 解析。

      tryit:捕獲函數在執行過程中可能拋出的同步或異步錯誤

      1. 使用說明
        1. 功能描述:tryit 是一個高階函數。用于捕獲函數在執行過程中可能拋出的同步或異步錯誤,并返回一個元組,其中包含錯誤對象或函數的返回值。這個函數的目的是提供一種安全執行任意函數并處理錯誤的方式。
        2. 參數:需要被捕獲的函數。
        3. 返回值:返回一個新函數,該函數接收與傳入函數相同的參數。
      2. 使用代碼示例
        import { tryit } from 'radash'
        
        const findUser = tryit(api.users.find)
        
        const [err, user] = await findUser(userId)
        
      3. 源碼解析
        // 定義一個泛型高階函數 `tryit`。
        export const tryit = <Args extends any[], Return>(
          // `func` 是一個接受任意參數的函數,其返回值可以是任何類型,包括 `Promise`。
          func: (...args: Args) => Return
        ) => {
          // 返回一個新函數,這個新函數接受與 `func` 相同的參數。
          return (
            ...args: Args
          // 新函數的返回類型取決于 `func` 的返回類型是否是 `Promise`。
          // 如果 `func` 返回 `Promise`,則返回一個 `Promise`,包含一個錯誤或函數返回值的元組。
          // 如果 `func` 返回非 `Promise`,則直接返回錯誤或函數返回值的元組。
          ): Return extends Promise<any>
            ? Promise<[Error, undefined] | [undefined, Awaited<Return>]>
            : [Error, undefined] | [undefined, Return] => {
            try {
              // 嘗試執行 `func` 并獲取結果。
              const result = func(...args)
              // 使用輔助函數 `isPromise` 檢查 `result` 是否是 `Promise`。
              if (isPromise(result)) {
                // 如果是 `Promise`,使用 `then` 和 `catch` 方法處理結果或捕獲錯誤。
                return result
                  .then(value => [undefined, value]) // 成功時返回值的元組。
                  .catch(err => [err, undefined]) // 錯誤時返回錯誤的元組。
              }
              // 如果 `result` 不是 `Promise`,直接返回值的元組。
              return [undefined, result]
            } catch (err) {
              // 如果執行 `func` 時捕獲到同步錯誤,返回錯誤的元組。
              return [err as any, undefined]
            }
          }
        }
        
        • 方法流程說明:
          1. tryit 函數接受一個函數 func 作為參數。
          2. tryit 返回一個新函數,這個新函數接受與 func 相同的參數。
          3. 當調用這個新函數時,它嘗試執行 func
          4. 如果 func 成功執行,且其返回值不是 Promise,新函數返回一個元組 [undefined, result]
          5. 如果 func 返回一個 Promise,新函數返回一個 Promise,該 Promise 解析為元組 [undefined, value][err, undefined],具體取決于 Promise 是成功解析還是被拒絕。
          6. 如果在執行 func 時捕獲到同步錯誤,新函數返回一個元組 [err, undefined]
          7. 如果 func 的返回類型是 Promise,那么新函數的返回類型也是 Promise,否則返回類型就是元組。

      寫在后面

      • 后續我們會繼續分享 Radash 庫中其他方法的使用和源碼解析。
      • 大家有任何問題或見解,歡迎評論區留言交流和批評指正!!!
      • 你的每一個點贊和收藏都是作者寫作的動力!!!
      • 點擊訪問:radash官網
      posted @ 2024-05-14 09:29  山里看瓜  閱讀(414)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产欧美精品一区aⅴ影院| 国产区成人精品视频| 国产玖玖玖玖精品电影| 国产成人免费一区二区三区| 亚洲人成网网址在线看| аⅴ天堂中文在线网| 在线视频观看| 怡春院久久国语视频免费| 久99久热免费视频播放| 中文字幕人妻中文AV不卡专区| caoporn免费视频公开| 一区二区亚洲精品国产精| 一本色道久久88亚洲精品综合| 欧洲美熟女乱又伦免费视频| 亚洲综合网国产精品一区| 边添小泬边狠狠躁视频| 国产一区二区三区精美视频| 十八禁午夜福利免费网站| 抚远县| 欧美粗大猛烈老熟妇| 韩国无码AV片在线观看网站| 人妻中文字幕精品系列| 国产精品一码二码三码四码| 少妇性l交大片| 激情内射亚洲一区二区三区| 精品人妻日韩中文字幕| 亚洲精品国产一二三区| 自偷自拍亚洲综合精品| 人妻偷拍一区二区三区| 极品无码国模国产在线观看| 久久精品国产蜜臀av| 乱色精品无码一区二区国产盗| 最近中文字幕免费手机版| 亚洲熟女乱色一区二区三区| 免费a级毛片无码av| 国产精品一区二区三区av| 自拍亚洲一区欧美另类| 色综合一本到久久亚洲91| 久久久亚洲欧洲日产国码农村| 国产综合久久99久久| 日本无产久久99精品久久|