or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-when

A lightweight Promises/A+ and when() implementation, plus other async goodies.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/when@3.7.x

To install, run

npx @tessl/cli install tessl/npm-when@3.7.0

0

# When.js

1

2

## Overview

3

4

When.js is a battle-tested Promises/A+ and when() implementation that provides a comprehensive suite of asynchronous utilities for JavaScript. It offers a powerful combination of small size, high performance, and rich features for managing complex asynchronous flows through promise chaining, error handling, and control flow utilities.

5

6

## Package Information

7

8

- **Name**: when

9

- **Type**: Promise library

10

- **Language**: JavaScript

11

- **Installation**: `npm install when`

12

13

## Core Imports

14

15

```typescript

16

// ESM

17

import when from "when";

18

import { resolve, reject, all, map } from "when";

19

20

// CommonJS

21

const when = require("when");

22

const { resolve, reject, all, map } = when;

23

24

// AMD

25

define(['when'], function(when) {

26

// use when

27

});

28

```

29

30

## Basic Usage

31

32

```typescript

33

// Create and transform promises

34

when(someValue)

35

.then(result => result * 2)

36

.catch(error => console.error('Error:', error));

37

38

// Promise creation

39

const promise = when.resolve("hello world");

40

const rejected = when.reject(new Error("failed"));

41

42

// Array processing

43

when.all([promise1, promise2, promise3])

44

.then(results => console.log('All resolved:', results));

45

```

46

47

## Core Promise API

48

49

### Main when() Function

50

51

```typescript { .api }

52

/**

53

* Get a trusted promise for value x, or transform x with callbacks

54

* @param x - Value or promise to resolve

55

* @param onFulfilled - Success callback

56

* @param onRejected - Error callback

57

* @param onProgress - Progress callback (deprecated)

58

* @returns Promise for the result

59

*/

60

function when<T, U>(

61

x: T | Promise<T>,

62

onFulfilled?: (value: T) => U | Promise<U>,

63

onRejected?: (reason: any) => U | Promise<U>,

64

onProgress?: (update: any) => void

65

): Promise<U>;

66

```

67

68

### Promise Creation

69

70

```typescript { .api }

71

/**

72

* Create a new promise with a resolver function

73

* @param resolver - Function that receives resolve, reject, notify callbacks

74

* @returns New promise

75

*/

76

function promise<T>(

77

resolver: (

78

resolve: (value: T) => void,

79

reject: (reason: any) => void,

80

notify: (progress: any) => void

81

) => void

82

): Promise<T>;

83

84

/**

85

* Create a resolved promise

86

* @param value - Value to resolve with

87

* @returns Promise resolved with value

88

*/

89

function resolve<T>(value: T | Promise<T>): Promise<T>;

90

91

/**

92

* Create a rejected promise

93

* @param reason - Rejection reason

94

* @returns Promise rejected with reason

95

*/

96

function reject<T = never>(reason: any): Promise<T>;

97

```

98

99

### Deferred Objects

100

101

```typescript { .api }

102

interface Deferred<T> {

103

/** The underlying promise */

104

promise: Promise<T>;

105

/** Resolve the promise */

106

resolve: (value: T) => void;

107

/** Reject the promise */

108

reject: (reason: any) => void;

109

/** Notify progress (deprecated) */

110

notify: (progress: any) => void;

111

/** Resolver object with resolve/reject/notify methods */

112

resolver: {

113

resolve: (value: T) => void;

114

reject: (reason: any) => void;

115

notify: (progress: any) => void;

116

};

117

}

118

119

/**

120

* Create a deferred promise/resolver pair

121

* @returns Deferred object with promise and resolver methods

122

*/

123

function defer<T>(): Deferred<T>;

124

```

125

126

## Function Lifting and Execution

127

128

### Function Lifting

129

130

```typescript { .api }

131

// Import from when/function module

132

import { lift, apply, call, compose } from "when/function";

133

134

/**

135

* Lift a function to work with promises as arguments and return promises

136

* @param f - Function to lift

137

* @returns Promise-aware version of the function

138

*/

139

function lift<TArgs extends any[], TResult>(

140

f: (...args: TArgs) => TResult

141

): (...args: { [K in keyof TArgs]: TArgs[K] | Promise<TArgs[K]> }) => Promise<TResult>;

142

143

/**

144

* Apply a function with args array and return a promise for its result

145

* @param f - Function to apply

146

* @param args - Arguments array to pass to function

147

* @returns Promise for function result

148

*/

149

function apply<TArgs extends any[], TResult>(

150

f: (...args: TArgs) => TResult,

151

args: TArgs

152

): Promise<TResult>;

153

154

/**

155

* Call a function and return a promise for its result (alias for when.try)

156

* @param f - Function to call

157

* @param args - Arguments to pass to function

158

* @returns Promise for function result

159

*/

160

function call<TResult>(f: () => TResult): Promise<TResult>;

161

function call<T1, TResult>(f: (arg1: T1) => TResult, arg1: T1): Promise<TResult>;

162

163

/**

164

* Compose functions into a promise-aware pipeline

165

* @param f - First function to receive arguments

166

* @param funcs - Additional functions to compose in sequence

167

* @returns Composed function that returns a promise

168

*/

169

function compose<TArgs extends any[], TResult>(

170

f: (...args: TArgs) => any,

171

...funcs: ((arg: any) => any)[]

172

): (...args: TArgs) => Promise<TResult>;

173

```

174

175

## Array and Collection Operations

176

177

### Promise Arrays

178

179

```typescript { .api }

180

/**

181

* Resolve all promises in an array

182

* @param promises - Array of promises or values

183

* @returns Promise for array of resolved values

184

*/

185

function all<T>(promises: (T | Promise<T>)[]): Promise<T[]>;

186

187

/**

188

* Settle all promises (resolve or reject) and return outcome descriptors

189

* @param promises - Array of promises or values

190

* @returns Promise for array of settlement descriptors

191

*/

192

function settle<T>(promises: (T | Promise<T>)[]): Promise<SettleDescriptor<T>[]>;

193

194

interface SettleDescriptor<T> {

195

state: "fulfilled" | "rejected";

196

value?: T;

197

reason?: any;

198

}

199

200

/**

201

* Join multiple promises (variadic version of all)

202

* @param promises - Promise arguments to join

203

* @returns Promise for array of resolved values

204

*/

205

function join<T extends any[]>(...promises: { [K in keyof T]: T[K] | Promise<T[K]> }): Promise<T>;

206

```

207

208

### Promise Racing

209

210

```typescript { .api }

211

/**

212

* Race promises, resolving with first to settle

213

* @param promises - Array of promises to race

214

* @returns Promise that resolves/rejects with first settlement

215

*/

216

function race<T>(promises: (T | Promise<T>)[]): Promise<T>;

217

218

/**

219

* Resolve with first promise to fulfill (ignores rejections until all reject)

220

* @param promises - Array of promises

221

* @returns Promise for first fulfilled value

222

*/

223

function any<T>(promises: (T | Promise<T>)[]): Promise<T>;

224

225

/**

226

* Resolve with first N promises to fulfill

227

* @param promises - Array of promises

228

* @param count - Number of fulfillments needed

229

* @returns Promise for array of first N fulfilled values

230

*/

231

function some<T>(promises: (T | Promise<T>)[], count: number): Promise<T[]>;

232

```

233

234

### Array Processing

235

236

```typescript { .api }

237

/**

238

* Promise-aware array map function

239

* @param promises - Array of promises or values

240

* @param mapFunc - Mapping function (may return promise)

241

* @returns Promise for array of mapped values

242

*/

243

function map<T, U>(

244

promises: (T | Promise<T>)[],

245

mapFunc: (value: T, index: number) => U | Promise<U>

246

): Promise<U[]>;

247

248

/**

249

* Promise-aware array filter function

250

* @param promises - Array of promises or values

251

* @param predicate - Filter predicate (may return promise)

252

* @returns Promise for array of filtered values

253

*/

254

function filter<T>(

255

promises: (T | Promise<T>)[],

256

predicate: (value: T, index: number) => boolean | Promise<boolean>

257

): Promise<T[]>;

258

259

/**

260

* Promise-aware array reduce function

261

* @param promises - Array of promises or values

262

* @param reducer - Reducer function (may return promise)

263

* @param initialValue - Initial accumulator value

264

* @returns Promise for final reduced value

265

*/

266

function reduce<T, U>(

267

promises: (T | Promise<T>)[],

268

reducer: (accumulator: U, value: T, index: number) => U | Promise<U>,

269

initialValue: U

270

): Promise<U>;

271

272

/**

273

* Promise-aware array reduceRight function

274

* @param promises - Array of promises or values

275

* @param reducer - Reducer function (may return promise)

276

* @param initialValue - Initial accumulator value

277

* @returns Promise for final reduced value

278

*/

279

function reduceRight<T, U>(

280

promises: (T | Promise<T>)[],

281

reducer: (accumulator: U, value: T, index: number) => U | Promise<U>,

282

initialValue: U

283

): Promise<U>;

284

```

285

286

## Promise Instance Methods

287

288

### Core Methods

289

290

```typescript { .api }

291

interface Promise<T> {

292

/**

293

* Standard Promises/A+ then method

294

* @param onFulfilled - Success callback

295

* @param onRejected - Error callback

296

* @param onProgress - Progress callback (deprecated)

297

* @returns New promise for callback result

298

*/

299

then<U>(

300

onFulfilled?: (value: T) => U | Promise<U>,

301

onRejected?: (reason: any) => U | Promise<U>,

302

onProgress?: (progress: any) => void

303

): Promise<U>;

304

305

/**

306

* Catch promise rejections

307

* @param onRejected - Error callback

308

* @returns New promise

309

*/

310

catch<U>(onRejected: (reason: any) => U | Promise<U>): Promise<T | U>;

311

312

/**

313

* Execute callback regardless of outcome

314

* @param onFinally - Cleanup callback

315

* @returns Promise with original value/reason

316

*/

317

finally(onFinally: () => void | Promise<void>): Promise<T>;

318

}

319

```

320

321

### Timing Methods

322

323

```typescript { .api }

324

interface Promise<T> {

325

/**

326

* Delay promise resolution

327

* @param ms - Delay in milliseconds

328

* @returns Promise that resolves after delay with same value

329

*/

330

delay(ms: number): Promise<T>;

331

332

/**

333

* Add timeout to promise

334

* @param ms - Timeout in milliseconds

335

* @param reason - Custom timeout reason

336

* @returns Promise that rejects if timeout exceeded

337

*/

338

timeout(ms: number, reason?: any): Promise<T>;

339

}

340

```

341

342

### Inspection and Utilities

343

344

```typescript { .api }

345

interface PromiseInspection<T> {

346

/** Current state of the promise */

347

state: "pending" | "fulfilled" | "rejected";

348

/** Resolved value (only if fulfilled) */

349

value?: T;

350

/** Rejection reason (only if rejected) */

351

reason?: any;

352

}

353

354

interface Promise<T> {

355

/**

356

* Synchronously inspect promise state

357

* @returns Inspection object with state and value/reason

358

*/

359

inspect(): PromiseInspection<T>;

360

361

/**

362

* Execute side effect without changing promise value

363

* @param onFulfilled - Side effect callback

364

* @returns Promise with original value

365

*/

366

tap(onFulfilled: (value: T) => void | Promise<void>): Promise<T>;

367

368

/**

369

* Spread array result as function arguments

370

* @param onFulfilled - Callback that receives spread arguments

371

* @returns Promise for callback result

372

*/

373

spread<U>(onFulfilled: (...values: T extends any[] ? T : [T]) => U | Promise<U>): Promise<U>;

374

}

375

```

376

377

## Object/Key Operations

378

379

```typescript { .api }

380

// Import from when/keys module

381

import { all as keysAll, map as keysMap, settle as keysSettle } from "when/keys";

382

383

/**

384

* Resolve all properties of an object

385

* @param object - Object with promise or value properties

386

* @returns Promise for object with resolved properties

387

*/

388

function keysAll<T extends Record<string, any>>(

389

object: { [K in keyof T]: T[K] | Promise<T[K]> }

390

): Promise<T>;

391

392

/**

393

* Map over object properties with promise-aware function

394

* @param object - Object to map over

395

* @param mapFunc - Mapping function for values

396

* @returns Promise for object with mapped values

397

*/

398

function keysMap<T, U>(

399

object: Record<string, T | Promise<T>>,

400

mapFunc: (value: T, key: string) => U | Promise<U>

401

): Promise<Record<string, U>>;

402

403

/**

404

* Settle all properties of an object

405

* @param object - Object with promise or value properties

406

* @returns Promise for object with settlement descriptors

407

*/

408

function keysSettle<T extends Record<string, any>>(

409

object: { [K in keyof T]: T[K] | Promise<T[K]> }

410

): Promise<{ [K in keyof T]: SettleDescriptor<T[K]> }>;

411

```

412

413

## Task Flow Control

414

415

### Parallel Execution

416

417

```typescript { .api }

418

/**

419

* Run array of tasks in parallel with same arguments

420

* @param tasks - Array of task functions

421

* @param args - Arguments to pass to all tasks

422

* @returns Promise for array of task results

423

*/

424

function parallel<T extends any[], U>(

425

tasks: ((...args: T) => U | Promise<U>)[],

426

...args: T

427

): Promise<U[]>;

428

```

429

430

### Sequential Execution

431

432

```typescript { .api }

433

/**

434

* Run array of tasks in sequence with same arguments

435

* @param tasks - Array of task functions

436

* @param args - Arguments to pass to all tasks

437

* @returns Promise for array of task results

438

*/

439

function sequence<T extends any[], U>(

440

tasks: ((...args: T) => U | Promise<U>)[],

441

...args: T

442

): Promise<U[]>;

443

```

444

445

### Pipeline Execution

446

447

```typescript { .api }

448

/**

449

* Run tasks in pipeline where each receives result of previous

450

* @param tasks - Array of task functions

451

* @param initialArgs - Arguments for first task

452

* @returns Promise for final task result

453

*/

454

function pipeline<T extends any[], U>(

455

tasks: [(...args: T) => any, ...((arg: any) => any)[]],

456

...initialArgs: T

457

): Promise<U>;

458

```

459

460

## Polling and Monitoring

461

462

```typescript { .api }

463

interface CancelablePromise<T> extends Promise<T> {

464

/** Cancel the polling operation */

465

cancel(): void;

466

}

467

468

/**

469

* Poll a task until condition is met or cancelled

470

* @param task - Task function to poll

471

* @param interval - Polling interval in milliseconds

472

* @param verifier - Optional condition verifier

473

* @returns Cancelable promise for polling result

474

*/

475

function poll<T>(

476

task: () => T | Promise<T>,

477

interval: number,

478

verifier?: (result: T) => boolean | Promise<boolean>

479

): CancelablePromise<T>;

480

```

481

482

## Callback Integration

483

484

### Callback Lifting

485

486

```typescript { .api }

487

// Import from when/callbacks module

488

import { lift, apply, call, promisify } from "when/callbacks";

489

490

/**

491

* Lift callback-style function to promise-returning function

492

* @param callbackFunc - Function expecting callback(err, result)

493

* @returns Promise-returning version of function

494

*/

495

function lift<TArgs extends any[], TResult>(

496

callbackFunc: (...args: [...TArgs, (err: any, result?: TResult) => void]) => void

497

): (...args: TArgs) => Promise<TResult>;

498

499

/**

500

* Apply callback-style function with args array and return promise

501

* @param callbackFunc - Function expecting callback(err, result)

502

* @param args - Arguments array for function

503

* @returns Promise for function result

504

*/

505

function apply<TArgs extends any[], TResult>(

506

callbackFunc: (...args: [...TArgs, (err: any, result?: TResult) => void]) => void,

507

args: TArgs

508

): Promise<TResult>;

509

510

/**

511

* Call callback-style function with individual arguments

512

* @param callbackFunc - Function expecting callback(err, result)

513

* @param args - Arguments for function

514

* @returns Promise for function result

515

*/

516

function call<TArgs extends any[], TResult>(

517

callbackFunc: (...args: [...TArgs, (err: any, result?: TResult) => void]) => void,

518

...args: TArgs

519

): Promise<TResult>;

520

```

521

522

### Node.js Integration

523

524

```typescript { .api }

525

// Import from when/node module

526

import { lift, apply, call, createCallback, bindCallback, liftCallback } from "when/node";

527

528

/**

529

* Lift Node.js-style callback function to promise-returning function

530

* @param nodeFunc - Function expecting Node-style callback(err, result)

531

* @returns Promise-returning version of function

532

*/

533

function lift<TArgs extends any[], TResult>(

534

nodeFunc: (...args: [...TArgs, (err: any, result?: TResult) => void]) => void

535

): (...args: TArgs) => Promise<TResult>;

536

537

/**

538

* Apply Node.js-style function with args array and return promise

539

* @param nodeFunc - Function expecting Node-style callback(err, result)

540

* @param args - Arguments array for function

541

* @returns Promise for function result

542

*/

543

function apply<TArgs extends any[], TResult>(

544

nodeFunc: (...args: [...TArgs, (err: any, result?: TResult) => void]) => void,

545

args: TArgs

546

): Promise<TResult>;

547

548

/**

549

* Call Node.js-style function with individual arguments and return promise

550

* @param nodeFunc - Function expecting Node-style callback(err, result)

551

* @param args - Arguments for function

552

* @returns Promise for function result

553

*/

554

function call<TArgs extends any[], TResult>(

555

nodeFunc: (...args: [...TArgs, (err: any, result?: TResult) => void]) => void,

556

...args: TArgs

557

): Promise<TResult>;

558

559

/**

560

* Create a Node.js-style callback from a resolver

561

* @param resolver - Promise resolver with resolve/reject methods

562

* @returns Node-style callback function

563

*/

564

function createCallback(resolver: {

565

resolve: (value: any) => void;

566

reject: (reason: any) => void;

567

}): (err: any, value?: any) => void;

568

569

/**

570

* Bind a Node.js-style callback to a promise

571

* @param promise - Promise to bind callback to

572

* @param callback - Node-style callback function

573

* @returns Promise with same state as input promise

574

*/

575

function bindCallback<T>(

576

promise: Promise<T>,

577

callback: (err: any, value?: T) => void

578

): Promise<T>;

579

580

/**

581

* Lift a Node.js-style callback to accept promises

582

* @param callback - Node-style callback to lift

583

* @returns Function that accepts a promise and calls callback on resolution

584

*/

585

function liftCallback(

586

callback: (err: any, value?: any) => void

587

): (promise: Promise<any>) => Promise<any>;

588

```

589

590

## Utilities

591

592

### Type Guards

593

594

```typescript { .api }

595

/**

596

* Check if value is thenable (promise-like)

597

* @param x - Value to test

598

* @returns True if value has then method

599

*/

600

function isPromiseLike(x: any): x is Promise<any>;

601

```

602

603

### Error Types

604

605

```typescript { .api }

606

/**

607

* Error thrown when promise times out

608

*/

609

class TimeoutError extends Error {

610

constructor(message?: string);

611

}

612

```

613

614

## Module Exports

615

616

When.js provides multiple ways to access its functionality:

617

618

```typescript

619

// Main module exports

620

import when from "when";

621

import * as callbacks from "when/callbacks";

622

import * as fn from "when/function";

623

import * as keys from "when/keys";

624

import * as node from "when/node";

625

import parallel from "when/parallel";

626

import sequence from "when/sequence";

627

import pipeline from "when/pipeline";

628

import poll from "when/poll";

629

import delay from "when/delay";

630

import timeout from "when/timeout";

631

import guard from "when/guard";

632

import * as generator from "when/generator";

633

634

// ES6 Promise shim

635

import Promise from "when/es6-shim/Promise";

636

```

637

638

## Common Patterns

639

640

### Promise Chaining

641

```typescript

642

when(getData())

643

.then(processData)

644

.then(saveData)

645

.catch(handleError)

646

.finally(cleanup);

647

```

648

649

### Error Propagation

650

```typescript

651

when.resolve(value)

652

.then(step1)

653

.catch(recoverFromStep1Error)

654

.then(step2)

655

.catch(handleFinalError);

656

```

657

658

### Array Processing

659

```typescript

660

const urls = ['url1', 'url2', 'url3'];

661

when.map(urls, fetchUrl)

662

.then(results => when.all(results.map(processResponse)))

663

.then(processedData => console.log('All done:', processedData));

664

```

665

666

### Conditional Processing

667

```typescript

668

when(condition)

669

.then(result => result ? doSomething() : doSomethingElse())

670

.then(handleResult);

671

```

672

673

## Execution Guards

674

675

```typescript { .api }

676

// Import from when/guard module

677

import guard from "when/guard";

678

679

/**

680

* Create guarded version of function that can only execute when condition allows

681

* @param condition - Function that returns promise for condition check

682

* @param f - Function to guard

683

* @returns Guarded version of function

684

*/

685

function guard<TArgs extends any[], TResult>(

686

condition: () => Promise<any>,

687

f: (...args: TArgs) => TResult | Promise<TResult>

688

): (...args: TArgs) => Promise<TResult>;

689

690

/**

691

* Create guard that limits concurrent executions to N

692

* @param count - Maximum number of concurrent executions

693

* @returns Guard condition function

694

*/

695

function guardN(count: number): () => Promise<any>;

696

```

697

698

## Generator Support

699

700

```typescript { .api }

701

// Import from when/generator module

702

import { lift as liftGenerator, call as callGenerator, apply as applyGenerator } from "when/generator";

703

704

/**

705

* Lift a generator function to work with promises and yield

706

* @param generator - Generator function to lift

707

* @returns Promise-aware generator function

708

*/

709

function liftGenerator<TArgs extends any[], TResult>(

710

generator: (...args: TArgs) => Generator<any, TResult, any>

711

): (...args: TArgs) => Promise<TResult>;

712

713

/**

714

* Call generator immediately as promise-aware coroutine

715

* @param generator - Generator function to call

716

* @param args - Arguments to pass to generator

717

* @returns Promise for generator result

718

*/

719

function callGenerator<TArgs extends any[], TResult>(

720

generator: (...args: TArgs) => Generator<any, TResult, any>,

721

...args: TArgs

722

): Promise<TResult>;

723

724

/**

725

* Apply generator with args array as promise-aware coroutine

726

* @param generator - Generator function to apply

727

* @param args - Arguments array for generator

728

* @returns Promise for generator result

729

*/

730

function applyGenerator<TArgs extends any[], TResult>(

731

generator: (...args: TArgs) => Generator<any, TResult, any>,

732

args: TArgs

733

): Promise<TResult>;

734

```

735

736

## Deprecated Modules

737

738

### Standalone Delay (Deprecated)

739

740

```typescript { .api }

741

// Import from when/delay (deprecated - use promise.delay() instead)

742

import delay from "when/delay";

743

744

/**

745

* Create promise that resolves after delay

746

* @deprecated Use when(value).delay(ms) instead

747

* @param ms - Delay in milliseconds

748

* @param value - Value to resolve with after delay

749

* @returns Promise that resolves after delay

750

*/

751

function delay<T>(ms: number, value?: T): Promise<T>;

752

```

753

754

### Standalone Timeout (Deprecated)

755

756

```typescript { .api }

757

// Import from when/timeout (deprecated - use promise.timeout() instead)

758

import timeout from "when/timeout";

759

760

/**

761

* Create promise that times out

762

* @deprecated Use when(promise).timeout(ms) instead

763

* @param ms - Timeout in milliseconds

764

* @param promise - Promise to add timeout to

765

* @returns Promise that rejects if timeout exceeded

766

*/

767

function timeout<T>(ms: number, promise: Promise<T>): Promise<T>;

768

```

769

770

### Unfold Utilities (Deprecated)

771

772

```typescript { .api }

773

// Import from when/unfold (deprecated - use cujojs/most streams instead)

774

import unfold from "when/unfold";

775

import { unfold as unfoldList } from "when/unfold/list";

776

777

/**

778

* Generate promise stream from generator function

779

* @deprecated Use cujojs/most streams instead

780

* @param generator - Function that generates values

781

* @param condition - Condition function to stop generation

782

* @param seed - Initial seed value

783

* @returns Promise for generated sequence

784

*/

785

function unfold<T, U>(

786

generator: (seed: T) => U | Promise<U>,

787

condition: (value: U, seed: T) => boolean | Promise<boolean>,

788

seed: T

789

): Promise<U[]>;

790

```