Skip to content

⬅️ Back to Table of Contents

📄 useAsyncQueue

📊 Analysis Summary

Metric Count
🔧 Functions 3
📦 Imports 4
⚡ Async/Await Patterns 2
🟢 Vue Composition API 1
📐 Interfaces 3
📑 Type Aliases 2

📚 Table of Contents

🛠️ File Location:

📂 packages/core/useAsyncQueue/index.ts

📦 Imports

Name Source
ShallowRef vue
noop @vueuse/shared
reactive vue
shallowRef vue

Async/Await Patterns

Type Function Await Expressions Promise Chains
promise-chain useAsyncQueue none prev .then((prevRes) => { if (signal?.aborted) { updateResult(promiseState.ab...
promise-chain whenAborted none new Promise(...)

Vue Composition API

Name Type Reactive Variables Composables
reactive reactive none none

Functions

useAsyncQueue(tasks: S & Array<UseAsyncQueueTask<any>>, options: UseAsyncQueueOptions): UseAsyncQueueReturn<{ [P in keyof T]: UseAsyncQueueResult<T…

Asynchronous queue task controller.

Parameters:

  • tasks any: No description
  • options any: No description

See: https://vueuse.org/useAsyncQueue

Raw JSDoc
/**
 * Asynchronous queue task controller.
 *
 * @see https://vueuse.org/useAsyncQueue
 * @param tasks
 * @param options
 */

Calls:

  • Array.from
  • reactive (from vue)
  • shallowRef (from vue)
  • onFinished
  • tasks.reduce
  • `prev .then((prevRes) => { if (signal?.aborted) { updateResult(promiseState.aborted, new Error('aborted')) return }
    if (
      result[activeIndex.value]?.state === promiseState.rejected
      && interrupt
    ) {
      onFinished()
      return
    }
    
    const done = curr(prevRes).then((currentRes: any) => {
      updateResult(promiseState.fulfilled, currentRes)
      if (activeIndex.value === tasks.length - 1)
        onFinished()
      return currentRes
    })
    
    if (!signal)
      return done
    
    return Promise.race([done, whenAborted(signal)])
    

    }) .catch-updateResult-onError-Promise.resolve`

Code
export function useAsyncQueue<T extends any[], S = MapQueueTask<T>>(
  tasks: S & Array<UseAsyncQueueTask<any>>,
  options?: UseAsyncQueueOptions,
): UseAsyncQueueReturn<{ [P in keyof T]: UseAsyncQueueResult<T[P]> }> {
  const {
    interrupt = true,
    onError = noop,
    onFinished = noop,
    signal,
  } = options || {}

  const promiseState: Record<
    UseAsyncQueueResult<T>['state'],
    UseAsyncQueueResult<T>['state']
  > = {
    aborted: 'aborted',
    fulfilled: 'fulfilled',
    pending: 'pending',
    rejected: 'rejected',
  }

  const initialResult = Array.from(Array.from({ length: tasks.length }), () => ({ state: promiseState.pending, data: null }))

  const result = reactive(initialResult) as { [P in keyof T]: UseAsyncQueueResult<T[P]> }

  const activeIndex = shallowRef<number>(-1)

  if (!tasks || tasks.length === 0) {
    onFinished()
    return {
      activeIndex,
      result,
    }
  }

  function updateResult(state: UseAsyncQueueResult<T>['state'], res: unknown) {
    activeIndex.value++
    result[activeIndex.value].data = res as T
    result[activeIndex.value].state = state
  }

  tasks.reduce((prev, curr) => {
    return prev
      .then((prevRes) => {
        if (signal?.aborted) {
          updateResult(promiseState.aborted, new Error('aborted'))
          return
        }

        if (
          result[activeIndex.value]?.state === promiseState.rejected
          && interrupt
        ) {
          onFinished()
          return
        }

        const done = curr(prevRes).then((currentRes: any) => {
          updateResult(promiseState.fulfilled, currentRes)
          if (activeIndex.value === tasks.length - 1)
            onFinished()
          return currentRes
        })

        if (!signal)
          return done

        return Promise.race([done, whenAborted(signal)])
      })
      .catch((e) => {
        if (signal?.aborted) {
          updateResult(promiseState.aborted, e)
          return e
        }

        updateResult(promiseState.rejected, e)
        onError()
        if (activeIndex.value === tasks.length - 1)
          onFinished()
        return e
      })
  }, Promise.resolve())

  return {
    activeIndex,
    result,
  }
}

whenAborted(signal: AbortSignal): Promise<never>

Parameters:

  • signal AbortSignal

Returns: Promise<never>

Calls:

  • reject
  • signal.addEventListener
Code
function whenAborted(signal: AbortSignal): Promise<never> {
  return new Promise((resolve, reject) => {
    const error = new Error('aborted')

    if (signal.aborted)
      reject(error)
    else
      signal.addEventListener('abort', () => reject(error), { once: true })
  })
}

Internal helpers

Declared inside another function in this file.

updateResult(state: UseAsyncQueueResult<T>['state'], res: unknown): void

Parameters:

  • state UseAsyncQueueResult<T>['state']
  • res unknown

Returns: void

Code
function updateResult(state: UseAsyncQueueResult<T>['state'], res: unknown) {
    activeIndex.value++
    result[activeIndex.value].data = res as T
    result[activeIndex.value].state = state
  }

Interfaces

UseAsyncQueueResult<T>

Interface Code
export interface UseAsyncQueueResult<T> {
  state: 'aborted' | 'fulfilled' | 'pending' | 'rejected'
  data: T | null
}

Properties

Name Type Optional Description
state 'aborted' \| 'fulfilled' \| 'pending' \| 'rejected' not shown
data T \| null not shown

UseAsyncQueueReturn<T>

Interface Code
export interface UseAsyncQueueReturn<T> {
  activeIndex: ShallowRef<number>
  result: T
}

Properties

Name Type Optional Description
activeIndex ShallowRef<number> not shown
result T not shown

UseAsyncQueueOptions

Interface Code
export interface UseAsyncQueueOptions {
  /**
   * Interrupt tasks when current task fails.
   *
   * @default true
   */
  interrupt?: boolean

  /**
   * Trigger it when the tasks fails.
   *
   */
  onError?: () => void

  /**
   * Trigger it when the tasks ends.
   *
   */
  onFinished?: () => void

  /**
   * A AbortSignal that can be used to abort the task.
   */
  signal?: AbortSignal
}

Properties

Name Type Optional Description
interrupt boolean not shown
onError () => void not shown
onFinished () => void not shown
signal AbortSignal not shown

Type Aliases

UseAsyncQueueTask<T>

type UseAsyncQueueTask<T> = (...args: any[]) => T | Promise<T>;

MapQueueTask<T extends any[]>

type MapQueueTask<T extends any[]> = {
  [K in keyof T]: UseAsyncQueueTask<T[K]>
};

Generated by Syntax Scribe