Maison >interface Web >js tutoriel >Publication d'une bibliothèque pour l'exécution synchrone de processus asynchrones dans JS/TS

Publication d'une bibliothèque pour l'exécution synchrone de processus asynchrones dans JS/TS

Susan Sarandon
Susan Sarandonoriginal
2024-12-21 02:44:09780parcourir

Released a Library for Synchronous Execution of Asynchronous Processes in JS/TS

J'ai publié une bibliothèque appelée sync-actions qui permet aux processus asynchrones d'être exécutés de manière synchrone en JavaScript/TypeScript. Surtout dans TypeScript, vous pouvez appeler des fonctions définies de manière sécurisée. Il est destiné à être utilisé dans les cas où vous souhaitez exécuter des processus asynchrones au sein de fonctions que vous ne voulez pas (ou ne pouvez pas) marquer comme asynchrones.

Caractéristiques

  • Utilise Node.js worker_threads
    • Les processus asynchrones sont exécutés dans un sous-thread et le thread principal attend de manière synchrone leur achèvement.
  • Appels de fonction de type sécurisé
    • Dans TypeScript, vous pouvez utiliser les informations de type des fonctions définies.
  • Publié en tant qu'ESM natif
    • C'est simplifié en ne prenant pas en charge CommonJS.

Dépôt

https://github.com/koyopro/sync-actions

Usage

Installation

Il est publié sous forme de package npm, veuillez donc l'installer à l'aide de npm install ou similaire.

npm install sync-actions

Utilisation de base

En passant une fonction asynchrone qui renvoie un objet Promise à definitionSyncWorker(), vous pouvez définir l'interface et démarrer le thread de travail avec launch(). On suppose que le fichier définissant le travailleur est créé séparément des autres fichiers de traitement.

// worker.js
import { defineSyncWorker } from "sync-actions";

export const { actions, worker } = defineSyncWorker(import.meta.filename, {
  ping: async () => {
    // Execute asynchronous process,
    await new Promise((resolve) => setTimeout(resolve, 1000));
    // Return the result as a return value
    return "pong";
  }
}).launch();
// main.js
import { actions, worker } from "./worker.js";

// You can execute asynchronous functions synchronously
console.log(actions.ping()); // => "pong" is output after 1 second

worker.terminate();

Appels de fonction de type sécurisé

Dans TypeScript, vous pouvez appeler les fonctions définies avec définirSyncWorker de manière sécurisée.

// worker.ts
import { defineSyncWorker } from "sync-actions";

export const { actions, worker } = defineSyncWorker(import.meta.filename, {
  // By specifying the types of arguments and return values, type-safe calls are possible
  add: async (a: number, b: number): Promise<number> => {
    return a + b;
  }
}).launch();
// main.ts
import { actions, worker } from "./worker.js";

// Type-safe call
actions.add(1, 2); // => 3 (number)

// @ts-expect-error
actions.add("1", 2);
// => Argument of type 'string' is not assignable to parameter of type 'number'

worker.terminate();

Arrière-plan

Le contenu jusqu'à présent est le même que celui du README, je vais donc décrire le contexte de sa création.

Je développe un ORM appelé Accel Record.1 Contrairement aux ORM généraux, Accel Record est conçu pour effectuer un accès à la base de données avec une interface synchrone.2 La partie qui exécute l'accès à la base de données de manière synchrone. a été réalisé en exécutant des processus asynchrones dans un sous-processus démarré avec le module child_process.3 Je pensais qu'en utilisant work_threads au lieu de child_process, je pourrais réduire la surcharge au moment de l'exécution.

Accel Record est également conçu pour être similaire à Active Record de Ruby on Rails en termes de convivialité, et l'une des choses que je souhaite réaliser à l'avenir est de créer une bibliothèque comme CarrierWave. CarrierWave vous permet d'enregistrer des images sur des services de stockage externes (tels qu'AWS S3) lors de l'enregistrement d'enregistrements, et pour y parvenir avec Accel Record, il est nécessaire d'exécuter des processus asynchrones tels que le téléchargement d'images de manière synchrone. Je m'attends à ce que ce processus puisse être exécuté plus rapidement en utilisant work_threads au lieu de sous-processus.

J'ai donc cherché une fois une bibliothèque qui exécute de manière synchrone des processus asynchrones à l'aide de worker_threads. J'ai trouvé plusieurs bibliothèques telles que synckit et deasync, mais aucune d'entre elles n'a fonctionné comme prévu de mon côté, j'ai donc décidé de créer la mienne. Depuis que j'y étais, j'ai pensé créer une interface pouvant être utilisée de manière sécurisée avec TypeScript.

Plus de détails internes

  • Jusqu'à ce que le processus asynchrone dans le sous-thread démarré avec worker_threads soit terminé, le thread principal est bloqué à l'aide d'Atomic.wait().
  • MessageChannel est utilisé pour la communication entre les threads. Le code source de synckit a été très utile pour cette partie de l'implémentation.
  • Lors du démarrage d'un Worker avec worker_threads, il est nécessaire de transpiler le fichier .ts en .js. Pour cette partie, j'utilise esbuild.
  • Lors du démarrage d'un Worker, je voulais transmettre le code source transpilé sous forme de chaîne au Worker pour exécution, mais cela ne fonctionnait pas correctement dans mon environnement. C’est la partie où j’ai le plus eu du mal. En fin de compte, j'ai écrit le fichier sous node_modules et transmis son chemin au Worker. Cette méthode s'est avérée la plus stable.

  1. Introduction à "Accel Record" : un ORM TypeScript utilisant le modèle d'enregistrement actif ↩

  2. Pourquoi nous avons adopté une API synchrone pour le nouvel ORM TypeScript ↩

  3. Techniques d'accès synchrone à la base de données dans TypeScript ↩

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn