278 votes

Appeler une fonction Javascript asynchrone de manière synchrone

Tout d'abord, il s'agit d'un cas très spécifique où l'on s'est trompé de méthode dans le but d'intégrer un appel asynchrone dans une base de code très synchrone qui compte plusieurs milliers de lignes et pour laquelle le temps ne permet pas actuellement d'effectuer les changements nécessaires pour "bien faire les choses". Cela fait mal à chaque fibre de mon être, mais la réalité et les idéaux ne s'accordent pas toujours. Je sais que ça craint.

OK, ceci étant dit, comment faire pour que je puisse.. :

function doSomething() {

  var data;

  function callBack(d) {
    data = d;
  }

  myAsynchronousCall(param1, callBack);

  // block here and return data when the callback is finished
  return data;
}

Les exemples (ou leur absence) utilisent tous des bibliothèques et/ou des compilateurs, qui ne sont pas viables pour cette solution. J'ai besoin d'un exemple concret de la façon dont on peut le faire bloquer (par exemple, ne PAS laisser la fonction doSomething jusqu'à ce que le callback soit appelé) SANS geler l'interface utilisateur. Si une telle chose est possible en JS.

17 votes

Il n'est tout simplement pas possible de bloquer un navigateur et d'attendre. Ils ne le feront tout simplement pas.

2 votes

Javascript n'a pas de mécanisme de blocage sur la plupart des navigateurs... vous devrez créer un callback qui sera appelé à la fin de l'appel asynchrone pour retourner les données.

0 votes

Je ne pense pas que cela puisse être fait. Javascript (malgré les web workers) est monofilaire - le callback ne peut pas être appelé avant le retour du gestionnaire d'événement actuel. Cela nécessiterait l'équivalent de la fonction async/await de C# en Javascript et je doute qu'une telle bête existe. Je crains que vous ne soyez obligé de réécrire votre code en CPS, aussi ennuyeux que cela puisse être.

0voto

dangtrunganh Points 1

Cette capacité des promesses comprend deux caractéristiques clés des opérations synchrones comme suit (ou then() accepte deux callbacks). Lorsque vous obtenez le résultat, appelez resolve() et transmettez le résultat final. En cas d'erreur, appelez reject().

L'idée est que le résultat est transmis par la chaîne de gestionnaires .then().

const synchronize = (() => {
    let chain = Promise.resolve()
    return async (promise) => {
        return chain = chain.then(promise)
    }
})()

-3voto

Nikhil Points 23

Vous pouvez également les convertir en callbacks.

function thirdPartyFoo(callback) {    
  callback("Hello World");    
}

function foo() {    
  var fooVariable;

  thirdPartyFoo(function(data) {
    fooVariable = data;
  });

  return fooVariable;
}

var temp = foo();  
console.log(temp);

-7voto

eragon512 Points 13

L'idée que vous espérez réaliser peut être rendue possible si vous modifiez un peu l'exigence.

Le code ci-dessous est possible si votre runtime supporte la spécification ES6.

En savoir plus fonctions asynchrones

async function myAsynchronousCall(param1) {
    // logic for myAsynchronous call
    return d;
}

function doSomething() {

  var data = await myAsynchronousCall(param1); //'blocks' here until the async call is finished
  return data;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X