2009-09-10 9 views
4

Il existe un tableau d'objets, qui sont développés avec des requêtes ajax parallèles. Lorsque la dernière requête est terminée, le tableau doit être traité. La seule solution que je vois est:Condition de concurrence asynchrone JavaScript

function expandArray(objects, callback){ 
    number_of_requests=objects.length-1; 
    for(i in objects){ 
    $.getJSON(request,function(){ 
       //expanding array   
       if(--number_of_reuests==0){ 
        callback(); 
       } 
       }); 
    } 
} 

Mais comme les demandes sont exécutées en parallèle, il y a un risque de condition de concurrence. La variable number_of_requests peut être éditée par deux "threads" simultanément. Comment éviter le risque de condition de course?

+1

Si 'objects' est un objet, il n'y a pas de propriété générique' length'. Et si c'est un tableau, vous ne devriez pas utiliser 'for ... in' mais le compte normal' for'. – Gumbo

+0

vous avez raison, mais il est possible que vous définissiez un objet avec une variable de longueur. – nickf

+3

JavaScript est mono-thread, il n'y a donc aucune possibilité de modification de la variable par deux threads séparés. – NickFitz

Répondre

2

Est-il possible de retravailler votre AJAX pour que tout se passe en une seule requête? Cette partie du système sera le plus gros goulot d'étranglement et peut devenir difficile (comme vous l'avez découvert), donc moins vous faites de demandes, mieux c'est. La seule autre manière que je pourrais penser serait si chaque demande a muté son objet relatif, en fixant une valeur de drapeau ou quelque chose, et alors vous avez bouclé à travers tous les objets pour vérifier si tous les drapeaux avaient été établis encore.

1

Est-ce que Javascript n'est pas threadé? Le genre de condition dont vous parlez ne se produirait pas.

+0

Oui, vous avez raison. Il n'y a pas de problème ici. –

+2

J'ai regardé la spécification JavaScript et rien ne dit que les implémentations JavaScript doivent être à un seul thread. –

+2

Quelques bonnes réponses sur ce problème: http://stackoverflow.com/questions/124764/are-mutexes-needed-in-javascript – itsadok

0

C'est plus complexe, mais je suggère d'utiliser une troisième fonction pour surveiller les résultats. Quelque chose comme ceci:

1) Lancer moniteur - à l'aide d'un moniteur intervalle approprié (en utilisant un intervalle de tester ici est important - une simple boucle serait verrouiller le moteur JS serré) les résultats des demandes A et B.

2) demande d'appel A.

3) demande d'appel B.

4) finitions demande B - fonction de rappel définit un "B All Done!" valeur.

5) Demande A finit - la fonction de rappel définit un "A Tout Fait!" valeur.

6) Le moniteur reconnaît que les deux demandes sont terminées et que les appels fonctionnent en utilisant les données des deux. Plus simplement, il s'agit de "dépendances" (appels multiples) à "surveiller" (la fonction qui vérifie les dépendances) à "achèvement" (l'action à effectuer lorsque tout est prêt).

Vous pouvez créer les fonctions de rappel et d'achèvement en tant que fonctions imbriquées pour maintenir l'encapsulation et réduire le nombre de «petites» dans la portée globale.

Vous pouvez étendre vos dépendances autant que vous le souhaitez.

+0

[async.js] (https://github.com/caolan/async) fournit une fonction appelée [async.parallel] (https://github.com/caolan/async#paralleltasks-callback) qui effectue les étapes 1 à 6. –

Questions connexes