diff --git a/lib/addons/p5.sound.js b/lib/addons/p5.sound.js index 761a42ff2f..f1fb294426 100644 --- a/lib/addons/p5.sound.js +++ b/lib/addons/p5.sound.js @@ -2945,11 +2945,10 @@ function () { }(); /** * loadSound() returns a new p5.SoundFile from a specified - * path. If called during preload(), the p5.SoundFile will be ready - * to play in time for setup() and draw(). If called outside of - * preload, the p5.SoundFile will not be ready immediately, so - * loadSound accepts a callback as the second parameter. Using a - * + * path. If used with asynchronous setup (via `async`/`await`), the p5.SoundFile + * will be ready to play in time for `setup()` and `draw()`. If called outside of an async context, + * the p5.SoundFile will not be ready immediately, so loadSound accepts a callback as the second + * parameter. Using a * local server is recommended when loading external files. * * @method loadSound diff --git a/src/core/main.js b/src/core/main.js index 3394715aa2..4777d11dc6 100644 --- a/src/core/main.js +++ b/src/core/main.js @@ -14,9 +14,10 @@ import * as constants from './constants'; * a p5 sketch. It expects an incoming sketch closure and it can also * take an optional node parameter for attaching the generated p5 canvas * to a node. The sketch closure takes the newly created p5 instance as - * its sole argument and may optionally set preload(), - * setup(), and/or - * draw() properties on it for running a sketch. + * its sole argument and may optionally set an asynchronous function + * using `async/await`, along with the standard setup(), + * and/or setup(), and/or draw() + * properties on it for running a sketch. * * A p5 sketch can run in "global" or "instance" mode: * "global" - all properties and methods are attached to the window @@ -465,6 +466,8 @@ for (const k in constants) { * draw() begins looping. If the * preload() is declared, then `setup()` will * run immediately after preload() finishes + * + * * loading assets. * * Note: `setup()` doesn’t have to be declared, but it’s common practice to do so. diff --git a/src/core/reference.js b/src/core/reference.js index 3ee337f7f8..c830ac5eaf 100644 --- a/src/core/reference.js +++ b/src/core/reference.js @@ -1137,6 +1137,115 @@ * */ + +/** + * Asynchronous Asset Loading with Async/Await. + * + * The keywords `async` and `await` let you write asynchronous code in a more + * straightforward, linear style. Instead of nesting callbacks or juggling + * multiple promise chains, you can pause execution at `await` while waiting + * for a promise to resolve. This makes your code flow more naturally, as if + * it were synchronous. + * + * When you mark a function with the `async` keyword—like `async function setup() {...}`—it + * signals that the function contains asynchronous operations and will return a + * promise. Any time you use the `await` keyword inside this function, JavaScript + * will pause the function’s execution until the awaited promise settles. + * + * In p5.js, you can use `async/await` to handle media loading functions such as + * `loadImage()`, `loadJSON()`, `loadSound()`, and so on. This allows you to: + * - load files in a more readable, top-to-bottom manner + * - decide when the assets are fully available before proceeding + * + * Nested callbacks require managing additional information and behavior. + * Lazy loading of assets with `async/await` can simplify control flow, + * but it also requires you to design your sketch around waiting for + * each operation to complete. + * + * Callbacks are still fully supported, so code that passes success / error + * functions to loaders like `loadImage()` or `loadJSON()` will behave exactly + * as it always has. This compatibility means sketches written with the older + * pattern don’t need any changes, and you can freely mix callbacks and + * `async/await` in the same project if that suits your workflow. + * + * In the example below, `setup()` is declared as an async function. We `await` + * the completion of both `loadImage()` and `loadJSON()` before calling + * `createCanvas()`. Only then does the sketch proceed, guaranteeing the assets + * are available for immediate use. + * + * ```js + * let img, data; + * + * async function setup() { + * // Wait until the image and JSON data have fully loaded. + * img = await loadImage("./my-image.png"); + * data = await loadJSON("./my-data.json"); + * + * // Once the assets are loaded, create the canvas. + * createCanvas(400, 400); + * } + * ``` + * + * @property async_await + * @example + *
+ * + * // Click and drag the mouse to view the scene from different angles. + * + * let shape; + * + * // Load the file and create a p5.Geometry object. + * async function setup() { + * shape = await loadModel('/assets/teapot.obj'); + * + * createCanvas(100, 100, WEBGL); + * + * describe('A white teapot drawn against a gray background.'); + * } + * + * function draw() { + * background(200); + * + * // Enable orbiting with the mouse. + * orbitControl(); + * + * // Draw the shape. + * model(shape); + * } + * + *
+ * + *
+ * + * let font; + * + * async function setup() { + * // Load a font for WebGL mode. + * font = await loadFont('assets/inconsolata.otf'); + * + * createCanvas(100, 100, WEBGL); + * + * describe( + * "A gray square. The mouse's x- and y-coordinates are displayed as the user moves the mouse." + * ); + * } + * + * function draw() { + * background(200); + * + * // Style the text. + * textAlign(CENTER); + * textSize(16); + * textFont(font); + * fill(0); + * + * // Display the mouse's coordinates. + * text(`x: ${mouseX} y: ${mouseY}`, 0, 0); + * } + * + *
+ */ + /** * A list that keeps several pieces of data in order. * diff --git a/src/utilities/time_date.js b/src/utilities/time_date.js index 4a98bc43c9..5a23b34dae 100644 --- a/src/utilities/time_date.js +++ b/src/utilities/time_date.js @@ -117,11 +117,10 @@ function timeDate(p5, fn){ * * If a sketch has a * setup() function, then `millis()` begins tracking - * time before the code in setup() runs. If a - * sketch includes a preload() function, then - * `millis()` begins tracking time as soon as the code in - * preload() starts running. - * + * time before the code in setup() runs. If a + * sketch includes asynchronous loading using `async`/`await`, then + * `millis()` begins tracking time as soon as the asynchronous code + * starts running. * @method millis * @return {Number} number of milliseconds since starting the sketch. *