Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

Scheduler: yield() method

Limited availability

Note: This feature is available inWeb Workers.

Experimental:This is anexperimental technology
Check theBrowser compatibility table carefully before using this in production.

Theyield() method of theScheduler interface is used for yielding to themain thread during a task and continuing execution later, with the continuation scheduled as a prioritized task (see thePrioritized Task Scheduling API for more information). This allows long-running work to be broken up so the browser stays responsive.

The task can continue when the promise returned by the method is resolved. The priority for when the promise is resolved defaults to"user-visible", but can inherit a different priority if theyield() call occurs within aScheduler.postTask() callback.

In addition, the continuation of work after theyield() call can be canceled if it occurs within apostTask() callback and thetask is aborted.

Syntax

js
yield()

Parameters

None.

Return value

Returns aPromise that is fulfilled withundefined, or rejected with anAbortSignal.reason.

Examples

Feature checking

Check whether prioritized task scheduling is supported by testing forscheduler.yield onglobalThis, either in a window or worker scope.

For example, the code below logs"scheduler.yield: Supported" if the API is supported in the current browser.

js
// Check for support before using.if (globalThis.scheduler?.yield) {  console.log("scheduler.yield: Supported");} else {  console.error("scheduler.yield: NOT Supported");}

Basic usage

Long tasks can be broken up by awaitingscheduler.yield(). The function returns a promise, yielding to the main thread to allow the browser to execute other pending work—like responding to user input—if needed. The browser schedules a follow-up task that resolves the promise, at which point execution of the code can continue where it left off.

For instance, if aclick event listener on a button results in significant work to load and display new page content, there will be no visual feedback to the user that their button click was even registered by the page until that work is complete. Ascheduler.yield() can be inserted into the event listener so that quick feedback can be shown (like a spinner), and then the remainder of the work can be done when execution continues after the yield.

js
button.addEventListener("click", async () => {  // Provide immediate feedback so the user knows their click was received.  showSpinner();  await scheduler.yield();  // Do longer processing  doSlowContentSwap();});

It may also be sufficient to provide quick interaction feedback with the default UI. For instance, if achange event listener on a checkbox triggers slow filtering of page content, ascheduler.yield() call can be inserted to show the check state change immediately before continuing to the remainder of the event response.

js
checkbox.addEventListener("change", async () => {  await scheduler.yield();  doSlowContentFiltering();});

In situations where there is lengthy work that needs to be done on the main thread that can be chunked into a series of tasks,scheduler.yield() can be called repeatedly to keep the page responsive throughout.

js
function doWork(value) {  console.log(`work chunk ${value}`);}const workList = [0, 1, 2, 3, 4];for (const work of workList) {  doWork(work);  await scheduler.yield();}

Yield priority

The order in which the promise returned byscheduler.yield() is resolved relative to other tasks is based on an implicittask priority.

By default,scheduler.yield() is run with a"user-visible" priority. However, continuation after ascheduler.yield() call has a slightly different behavior thanscheduler.postTask() tasks of the samepriority.

scheduler.yield() enqueues its task in a boosted task queue compared to ascheduler.postTask() of the same priority level. So, for instance, ascheduler.yield() continuation with"user-visible" priority will be prioritized afterscheduler.postTask() tasks of the higher"user-blocking" priority level, but beforescheduler.postTask() tasks of the same"user-visible" priority (in the spec, this is defined by a task queue'seffective priority).

This is sometimes described asscheduler.yield() enqueuing its task at the front of a priority level's queue, whilescheduler.postTask() tasks go at the end. This can be a useful mental model. In situations with just a few tasks, this means that with the same priority, thescheduler.yield() continuation will come first, allowing additional flexibility in how tasks can be scheduled. For example:

js
scheduler.postTask(() => console.log("user-visible postTask"));scheduler.postTask(() => console.log("user-blocking postTask"), {  priority: "user-blocking",});await scheduler.yield();console.log("user-visible yield");

will log the following:

user-blocking postTaskuser-visible yielduser-visible postTask

However, in cases where there are multiplescheduler.yield() calls, the distinction that thescheduler.yield() continuation tasks go into a boosted-priorityqueue becomes important because a secondscheduler.yield() task won't be run before one that's already in the queue.

If one function yields its work before a second function does, the first function to yield will continue first. For example:

js
async function first() {  console.log("starting first function");  await scheduler.yield();  console.log("ending first function");}async function second() {  console.log("starting second function");  await scheduler.yield();  console.log("ending second function");}first();second();

will log the following:

starting first functionstarting second functionending first functionending second function

Inheriting task priorities

Ascheduler.yield() call within ascheduler.postTask() task will inherit the task's priority. For example, work after ascheduler.yield() within a low-priority"background" task will also be scheduled as"background" by default (but, again, inserted in the boosted"background" priority queue so running before any"background"postTask() tasks).

For example:

js
async function backgroundWork() {  scheduler.postTask(() => console.log("background postTask"), {    priority: "background",  });  scheduler.postTask(() => console.log("user-visible postTask"), {    priority: "user-visible",  });  // yield() inherits "background" priority from surrounding task.  await scheduler.yield();  console.log("default-background yield");}await scheduler.postTask(backgroundWork, { priority: "background" });

will log the following:

user-visible postTaskdefault-background yieldbackground postTask

scheduler.yield() continuations will inherit whatever priority the containingscheduler.postTask() task has, including whether the task's priority waschanged dynamically.

Aborting a yield

Similar to setting priority, ascheduler.yield() call can't be aborted directly, but it will inherit the abort signal from a surroundingscheduler.postTask() task. Aborting the task will also abort any pending yields within it.

This example uses aTaskController toabort a task with ascheduler.yield() within it.

js
const taskController = new TaskController();function firstHalfOfWork() {  console.log("first half of work");  taskController.abort("cancel work");}function secondHalfOfWork() {  // Never runs.  console.log("second half of work");}scheduler.postTask(  async () => {    firstHalfOfWork();    await scheduler.yield();    secondHalfOfWork();  },  { signal: taskController.signal },);

The example is somewhat contrived in that it always triggers thetaskController.abort() call within the task itself, but theabort() call could come from anywhere. For example, it could be triggered by the user pressing a 'Cancel' button.

In this case, theabort() occurs after thescheduler.postTask() task has already started ("first half of work" is logged), but the yield call inherits theabort signal therefore theawait scheduler.yield() call will throw with an abort reason of"cancel work".

Usingyield() withinrequestIdleCallback()

scheduler.yield() calls also inherit their priority fromWindow.requestIdleCallback(), when called from inside the callback function. In this case, the"background" priority value is inherited. Note however thatscheduler.yield() calls insiderequestIdleCallback() callbacks are not abortable.

Specifications

Specification
Prioritized Task Scheduling
# dom-scheduler-yield

Browser compatibility

See also

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp