Blog
deferExecution() in Refine source code.

deferExecution() in Refine source code.

In this article, we will review a function named deferExecution() in Refine source code.

/**
 * Delays the execution of a callback function asynchronously.
 * This utility function is used to defer the execution of the provided
 * callback, allowing the current call stack to clear before the callback
 * is invoked. It is particularly useful for ensuring non-blocking behavior
 * and providing a clear intent when a 0 ms timeout is used.
 */
export const deferExecution = (fn: Function) => {
  setTimeout(fn, 0);
};

This above code snippet is picked from refinedev/refine/packages/core/src/definitions/helpers/defer-execution/index.ts

This code is inside a folder named defer-execution. It contains the files shown in the below image.

so what is deferExecution used for?

/**
  Delays the execution of a callback function asynchronously.  This utility function is used to defer the execution of the provided
  callback, allowing the current call stack to clear before the callback  is invoked. It is particularly useful for ensuring non-blocking behavior
  and providing a clear intent when a 0 ms timeout is used. /

This comment above the function explains clearly what this function is about. 

The time, in milliseconds that the timer should wait before the specified function or code is executed. If this parameter is omitted, a value of 0 is used, meaning execute “immediately”, or more accurately, the next event cycle. Read more about setTimeout.

Wait, what is event cycle? For that, you need to read about Job queue and event loop in JavaScript Execution Model documentation

A job is considered completed when the stack is empty; then, the next job is pulled from the queue. Jobs might not be pulled with uniform priority — for example, HTML event loops split jobs into two categories: tasks and microtasks. Microtasks have higher priority and the microtask queue is drained first before the task queue is pulled.

Okay, at this point, let’s go find out how this deferExecution is used in the Refine codebase.

deferExecution usage

if (!isPessimistic && !isAutosave) {
  // If the mutation mode is not pessimistic, handle the redirect immediately in an async manner
  // `setWarnWhen` blocks the redirects until set to `false`
  // If redirect is done before the value is properly set, it will be blocked.
  // We're deferring the execution of the redirect to ensure that the value is set properly.
  deferExecution(() => onSuccessRedirect());
  // Resolve the promise immediately
  resolve();
}

This code snippet is one instance picked from hooks/form/index.ts

But I am surprised there is no clean up in the sense that timeout is not cleared

Testing deferExecution()

You will find a file named defer-execution/index.spec.ts containing the below code:

import { waitFor } from "@testing-library/react";
import { deferExecution } from ".";

describe("deferExecution", () => {
  beforeEach(() => {
    jest.useRealTimers();
  });

  afterEach(() => {
    jest.useFakeTimers();
  });

  it("should defer the call after caller returns", async () => {
    const array: number[] = [];

    const fn = () => {
      array.push(1);

      deferExecution(() => {
        array.push(3);
      });

      array.push(2);
    };

    fn();

    await waitFor(() => {
      expect(array).toEqual([1, 2, 3]);
    });
  });
});

arr.push(3) is called inside deferExecution and the result is validated to [1, 2, 3]. 

About me:

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com

My Github — https://github.com/ramu-narasinga

My website — https://ramunarasinga.com

My Youtube channel — https://www.youtube.com/@thinkthroo

Learning platform — https://thinkthroo.com

Codebase Architecture — https://app.thinkthroo.com/architecture

Best practices — https://app.thinkthroo.com/best-practices

Production-grade projects — https://app.thinkthroo.com/production-grade-projects

References:

  1. https://github.com/refinedev/refine/blob/main/packages/core/src/definitions/helpers/defer-execution/index.ts#L8

  2. https://github.com/refinedev/refine/blob/main/packages/core/src/hooks/form/index.ts#L292

  3. https://github.com/refinedev/refine/tree/main/packages/core/src/definitions/helpers/defer-execution

  4. https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout

  5. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Execution_model#job_queue_and_event_loop

  6. https://github.com/refinedev/refine/blob/main/packages/core/src/definitions/helpers/defer-execution/index.spec.ts