Tool functions
The following sections introduce a set of tool functions in the @goldfishjs/core/utils package. 
cache(asyncTask, options?)
- Type:
function cache<R>(asyncTask: AsyncTask<R>, options?: CacheOptions): AsyncTaskWithCache<R>;
type AsyncTask<R> = () => Promise<R>;
type CacheOptions = {
  /**
   * When the execution of the first asynchronous task fails and an exception is thrown, if this configuration is set to true, the asynchronous task will be executed again on the second execution. Otherwise, the asynchronous task will not be executed again on the second execution and the exception result of the first execution will be returned.
   */
  shouldRerunWhenError?: boolean;
  /**
   * The cache time, in ms
   * -1 indicates the memory-based permanent cache.
   * 2000 ms by default
   */
  time?: number;
}
type AsyncTaskWithCache<R> = AsyncTask<R>;- Details:
Caches the execution result of the asynchronous function.
- Example:
import { cache } from '@goldfishjs/core/utils';
let counter: number = 1;
let asyncTask = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(counter++);
    });
  });
};
let asyncTaskWithCache = cache(asyncTask);
console.log(await asyncTaskWithCache());
console.log(await asyncTaskWithCache());
console.log(await asyncTaskWithCache());
// Print:
// 1
// 1
// 1
asyncTask = () => {
  return new Promise((_, reject) => {
    setTimeout(() => {
      counter++;
      reject(new Error('Some error.'));
    });
  });
};
asyncTaskWithCache = cache(asyncTask);
try {
  await asyncTaskWithCache();
  console.log(counter);
} catch {}
try {
  await asyncTaskWithCache();
  console.log(counter);
} catch {}
try {
  await asyncTaskWithCache();
  console.log(counter);
} catch {}
// Print:
// 2
// 3
// 4
parseUrl(url)
- Type:
function parseUrl(url: string): UrlParseResult;
interface UrlParseResult {
  username: string;
  password: string;
  port: string;
  host: string;
  pathname: string;
  href: string;
  search: string;
  protocol: string;
  hash: string;
};
- Details:
Parses a URL and returns the objects constructed by various components of the URL.
silent
- Type:
interface silent {
  <FnType extends FunctionType>(syncTask: FnType): ReturnWithNull<FnType>;
  async<FnType extends PromiseCreator>(asyncTask: FnType): ResolveWithNull<FnType>;
}
function silent<FnType extends FunctionType>(task: FnType): ReturnWithNull<FnType>;
type FunctionType = (...args: any[]) => any;
type ReturnWithNull<FnType extends FunctionType> = (...args: Parameters<FnType>) => ReturnType<FnType> | null;
type ResolveWithNull<FnType extends PromiseCreator> = (
  ...args: Parameters<FnType>
) => ReturnType<FnType> | Promise<null>;- Details:
Synchronously or asynchronously executes the task function. When an exception is thrown during execution, the silent() function will print the exception content on the console instead of throwing the exception.
- Example:
import { silent } from '@goldfishjs/core/utils';
function syncTask() {
  throw new Error('some error!');
}
function asyncTask() {
  return new Promise((_, reject) => {
    setTimeout(() => {
      reject(new Error('some error!'));
    });
  });
}
// Execute task synchronously
// Print the exception content on the console without affecting subsequent code execution.
silent(syncTask)();
// Execute task asynchronously
// Print the exception content on the console without affecting subsequent code execution.
await silent.async(syncTask)();
isObject(value)
- Type:
function isObject(value: any): value is Record<string, any>;- Details:
Determines whether the value is an object and excludes null.
interval(callback, duration)
- Type:
function interval(callback: () => void, duration: number): Stop;
type Stop = () => void;- Details:
Uses the setTimeout function to implement the timer trigger.
Note: We recommend using the
setTimeoutfunction. If you use thesetIntervalfunction directly on mobile terminals, the interval for calling thecallbackfunction is likely to be much longer than the specified interval.
deepVisit(data, callback)
- Type:
function deepVisit(data: any, callback: Callback): void;
interface Callback {
  (currentValue: any, currentKey: string | number, parentData: Record<string, any>, keyPathList: (string | number)[]): DeepVisitBreak;
}
enum DeepVisitBreak {
  ALL,
  CHILDREN,
  NO,
}- Details:
Deeply traverses the objects. For each traversal node, the callback function is called, with the following parameters:
- {any} currentValue: The value of the current traversal node.
- {string} currentKey: The key of the current traversal node.
- {Record<string, any>} parentData: The parent object where the current node is located.
- {string[]} keyPathList: The path to the key of the current node.
The return value of the callback function is used to determine whether to terminate traversal and how to terminate:
- DeepVisitBreak.ALL: Stop the traversal of the entire object and exit.
- DeepVisitBreak.CHILDREN: Stop the traversal of the remaining sibling nodes of the current node and go to the next node to be traversed in the parent node and proceed with the traversal.
- DeepVisitBreak.NO: Continue traversing the next node.
The deepVisit function can also traverse circular reference objects. 
- Example:
import { deepVisit } from '@goldfishjs/core/utils';
const data = {
  address: {
    city: 'Hangzhou',
  },
};
deepVisit(data, (_, currentKey) => {
  // Print:
  // address
  // city
  console.log(currentKey);
});
commonError(value)
- Type:
async function commonError(value: any): Promise<[any, CommonError?]>;
export interface CommonError {
  message: string;
  // Error codes:
  // If the value is a string, the code is UNKNOWN.
  // If the value is an error instance, the code is Error#name.
  // If the value is a function, it depends on the execution result of the function:
  //   - When the function throws an exception, call the commonError function to wrap the exception value.
  //   - When the function returns normally, no commonError object will be returned.
  // In other cases, the code is UNSUPPORTED. 
  code:
    | 'UNKNOWN'
    | 'UNSUPPORTED'
    | 'Error'
    | 'TypeError'
    | 'EvalError'
    | 'InternalError'
    | 'RangeError'
    | 'ReferenceError'
    | 'SyntaxError'
    | 'URIError'
    | string;
  raw: any;
}- Details:
Wraps errors for easy processing.
The values of the parameters in the commonError function can be any data type. The logic for handling different types of values is as follows:
- For a function (asynchronous):
- If an exception is thrown, the exception object is wrapped as a parameter of the commonErrorfunction.
- Otherwise, a wrapped object that indicates success is returned.
- For an error instance, a wrapped error object is returned.
- For a string, it is regarded as an error message and a wrapped error object is returned.
- For other cases, UNSUPPORTEDis returned.
The return value of the commonError function is an array:
- If an error occurs, the return value contains two elements. The first element is undefinedwhile the second one is a wrapped error object and the type iscommonError.
- If no error occurs, the return value contains one element, which indicates success.
- Example:
import {} from '@goldfishjs/core/utils';
function request() {
  return new Promise((_, reject) => {
    setTimeout(() => {
      reject(new Error('request error'));
    });
  });
}
const [response, requestError] = await commonError(request);
isEqual
For details, see isEqual.
cloneDeep
For details, see cloneDeep.
find
For details, see find.
omit
For details, see omit.
pick
For details, see pick.