9
votes

Les rappels sont toujours asynchrones?

Cet exemple est JavaScript, car c'est là que j'utilise les rappels surtout. Je veux comprendre comment ils travaillent à un niveau bas.

Dans l'exemple ci-dessous, je m'attendrais à ce que tout se produise dans l'ordre et "rappel" pour se produire après "étape 3" et avant "Étape 4." Cela a du sens pour moi, car tout est fait pour un seul fil d'exécution. Il n'y a pas de tromperie. La seule chose qui est en quelque sorte spéciale, c'est que vous avez passé une fonction à une autre fonction. xxx

Comment créeriez-vous DOSOMODRON asynchrone pour que "Étape 4" peut être exécuté avant ou parallèlement, "Étape 3"?

Je suppose que si DOSMATHIAT était appelé d'une manière asynchrone, il faudrait être sur un fil différent, non? Et si oui, quand il finit puis appelle myCallback , est-ce que le rappel se produit sur le deuxième fil ou sur le thread principal? Si cela se produit sur le fil principal, pourquoi ça se passe Le deuxième thread a même besoin d'un pointeur sur la fonction de rappel? Comment fonctionne l'appel inter-thread?


3 commentaires

Je suppose que c'est pas courir dans un navigateur, non? Parce que dans le navigateur, tout appel AJAX est nécessairement asynchrone ...


@Dean, Tout d'abord, les demandes XHR peuvent être synchrones (selon les paramètres de la demande). Deuxièmement, si vous lisez la question (et regardez son exemple de code), il ne s'agit pas d'Ajax.


@Dean, cela pourrait fonctionner dans un navigateur ou non. Je suis tout à fait intéressé à déterminer si la fonction de rappel est exécutée sur le thread principal ou le deuxième fil qui a été passé le pointeur de la fonction de rappel en tant que paramètre.


4 Réponses :


0
votes

Vous auriez besoin de plusieurs threads d'exécution pour faire cela, ce que je ne crois pas que vous puissiez faire en JavaScript (bien que corrige-moi si je me trompe). Toutefois, si vous écrivez un programme C / C ++, regardez le package Pthreads (ou libdispatch sur Mac OS X 10.6).

Edit: une recherche Google de "threads javascript" présente des résultats potentiellement intéressants.


0 commentaires

0
votes

Utilisation de rappels comme vous êtes (nom de déclaration de fonction ou nom de variable d'expression de fonction comme argument à une autre fonction), ils sont synchrones . Pour les rendre asynchrones, vous pouvez les envelopper dans un Settimeout .


0 commentaires

11
votes

webworkers Mister, le modèle de programmation JavaScript dans le navigateur est purement unique. Vous pouvez faire votre appel un peu asynchrone en utilisant fenêtre.settimeout : xxx

Cela place efficacement l'appel DOSMATHIQUE (MYCALLBACK) sur la file d'attente de la minuterie, et après 0 ou plusieurs millisecondes ELAPSE, il sera éventuellement invoqué. Cependant, comme avec tous les appels asynchrones en JavaScript, vous devez renoncer au contexte d'exécution avant que les rappels asynchrones puissent être invoqués; c'est-à-dire que la file d'attente de la minuterie ne sera pas traitée (et donc dosomething (myCallback) ne sera pas invoquée) jusqu'à ce que votre principal () Fonction fonction, en supposant que la fin de la fonction Votre JavaScript.

Une conséquence malheureuse de ce Settimeout -A-Based est que DOSMATHIAT (MYCALLBACK) n'est pas invoqué en parallèle à côté de console.log ("étape 4") . D'autre part, considérez xmlhttprequest.send ; Après avoir effectué cet appel, le reste de votre JS peut continuer à exécuter pendant que le navigateur émet la requête HTTP. Votre script a besoin de finir d'exécuter avant le ONREADYSTATECHANGE Handler peut exécuter, Mais la plupart des travaux de connexion HTTP peuvent se produire en parallèle pendant que JS exécute.


4 commentaires

Dans le cas , je suppose que cela se produit sur un autre fil. Quand c'est fait et que le OnreadyStatechange Handler s'exécute, quel fil fait cela se passe-t-il?


Cela se produit sur le fil JavaScript principal. Mise en œuvre, cela peut être n'importe quel fil, mais conceptuellement JavaScript (et le DOM, pour cette affaire) s'exécute dans un seul fil.


Je suppose que la partie déroutante est que cela s'appelle un "rappel". Cela, pour moi, dit "Voici une fonction, appelez ceci lorsque vous avez terminé de faire votre chose. Je vais faire ma propre chose." Lorsque vraiment, le navigateur termine l'appel AJAX puis interrompt le fil principal (via quel mécanisme ??) et le fil principal lui-même appelle la fonction qu'elle enregistrait comme rappel. Ai-je raison?


Conceptuellement, il n'y a pas d'interruption. Pendant un instant, prétendez que le monde n'a pas de concurrence au tout - vous demandez au navigateur de faire un appel AJAX ou de réagir aux clics de souris, mais il ne peut rien faire avant la fin de votre JS. Ce n'est qu'après ce point que le navigateur peut décider de vous informer que le serveur a répondu à votre appel AJAX ou que l'utilisateur a cliqué sur la page; L'interprète JS commence une fois de plus et exécute votre rappel. (Ce n'est pas trop éloigné - le navigateur ne peut pas traiter les événements cliquez, etc. pendant que votre JS fonctionne.)



5
votes

hmmm .. quelque chose ne va pas mal (j'ai fait v Little JavaScript): vous passez myCallback à la fonction DOSMATHIAT () mais vous ne le rappelez pas !? Vous devriez avoir un appel à F () à l'intérieur du dosage () ou transmettez-le à une autre fonction qui le rappellera une fois que votre longue opération est terminée .. Aucun rappel n'est intrinsèquement asynchrone - dans votre cas, vous exécutez tout cela. Sur le même fil (même si l'accès à l'accès à l'accès () est asynchrone auquel cas cela reviendrait immédiatement!) - Donc, il ira toujours Step1, Step2, Step3, Step4. Je crois que vous voulez:

function main() {
  console.log("step 1");
  console.log("step 2");
  doSomething(myCallBack);
  console.log("step 4");
}

function doSomething(f) {
  accessTheDatabase(f); // assuming this is an asynchronous operation and calls the callback f once done
}

function myCallBack() {
   console.log("step 3");
}


3 commentaires

Tu as raison! Merci pour la prise.


Mon plaisir, marquez-le comme la réponse si c'est :)


réponse mise à jour pour la 2e partie de votre question - quel filetage il est exécuté