Comment rendre cette fonction JS asynchrone?

function takesTime(){ for (var i = 0; i<some_very_large_number; i++){ //do something synchronous } console.log('a'); } takesTime(); console.log('b'); 

Cela imprime: a b Comment l'impressionz-vous imprimer: b a

Je vois que c'est marqué node.js, alors je vais répondre à cette perspective: vous ne devriez pas. Habituellement, si vous bloquez, ce sera: lié au réseau (vous devriez utiliser et / ou réutiliser les bibliothèques réseau autour de méthodes asynchrones), lié à l'E / S (vous devriez utiliser et / ou réutiliser les bibliothèques d'E / S ) , Ou lié à la CPU. Vous n'avez fourni aucun contexte pour savoir ce que la tâche de longue durée est, et étant donné que vous avez un invariant de boucle contenant un some_very_large_number , je suppose que vous some_very_large_number une tâche intensive en CPU itérant sur un grand champ.

Si vous êtes effectivement lié à la CPU, vous devriez repenser votre stratégie. Le nœud ne vit que sur un noyau, donc même si vous pouviez utiliser le multithreading, vous devriez vraiment faire tourner vos roues, car chaque requête nécessiterait encore une certaine quantité de temps CPU. Si vous avez l'intention de faire quelque chose d'intensif en termes de calcul, vous voudrez peut-être utiliser un système de mise en file d'attente et avoir autre chose à traiter les données mieux conçues pour le faire croquer.

 for (var i = 0; i < someVeryLargeNumber; ++i) { setTimeout(function () { //do something synchronous }, 0); } 

Voir aussi setZeroTimeout pour gagner quelques millisecondes chaque boucle, bien que les gens travaillent, cela semble être basé sur le navigateur.

Javascript est basé sur des événements, et tout se passe dans un seul thread. La façon dont vous l'obtenez "asynchrone" est d'utiliser un timeout (setTimeout ()).

Vous pouvez utiliser les opérateurs Web pour atteindre votre objectif, mais vous aurez besoin d'un fichier js distinct, et vous devrez ajouter un code de plomberie pour poster des messages et gérer ces messages.

Node.js ne prend pas en charge les opérateurs Web de manière native, mais une implémentation est disponible sur:

https://github.com/cramforce/node-worker/

Sinon, il est similaire au code suivant:

 Var pid = require ('child_process'). Spawn ('node', ['childScript.js'])
 Pid.stdout.on ('data', function (data) {
   Console.log (données);
 });
 Console.log ('b');

ChildScript.js

 Pour (var i = 0; i <some_very_large_number; i ++) {
   // fais quelque chose de synchrone
 }
 Console.log ('a');