Maison > interface Web > js tutoriel > le corps du texte

Explication détaillée des techniques Promises_javascript en Javascript et AngularJS

WBOY
Libérer: 2016-05-16 15:15:59
original
1208 Les gens l'ont consulté

Par exemple, les promesses sont utilisées lorsque la page appelle l'API Google Maps.

function success(position){
  var cords = position.coords;
  console.log(coords.latitude + coords.longitude);
}

function error(err){
  console.warn(err.code+err.message)
}

navigator.geolocation.getCurrentPosition(success, error);
 

Copier après la connexion

weight Comment gérer plusieurs méthodes asynchrones

Et s'il existe de nombreuses méthodes asynchrones qui doivent être exécutées séquentiellement ? async1(succès, échec), async2(succès, échec), ...asyncN(succès, échec), comment y faire face ?

Le plus simple pourrait s'écrire ainsi :

async1(function(){
  async2(function(){
    ...
    asyncN(null, null);
    ...
  }, null)
}, null)
 

Copier après la connexion

Le code ci-dessus est relativement difficile à maintenir.

Nous pouvons laisser apparaître une notification une fois que toutes les méthodes asynchrones sont exécutées.

var counter = N;
function success(){
  counter--;
  if(counter === 0){
    alert('done');
  }
}

async1(success);
async2(success);
...
asyncN(success);

 

Copier après la connexion

■ Que sont la promesse et le différé

deferred représente le résultat d'une opération asynchrone, fournit une interface pour afficher les résultats et l'état de l'opération et fournit une instance de promesse qui peut obtenir le résultat de l'opération. Le différé peut changer l’état de l’opération.

Promise fournit une interface pour interagir avec les différés associés.

Lors de la création d'un différé, cela équivaut à un état en attente
Lorsque la méthode de résolution est exécutée, elle équivaut à un état résolu.
Lorsque la méthode de rejet est exécutée, elle équivaut à un état rejeté.

Nous pouvons définir une fonction de rappel après avoir créé le différé, et la fonction de rappel commencera à s'exécuter après avoir reçu les invites d'état résolues et rejetées. La méthode asynchrone n'a pas besoin de savoir comment fonctionne la fonction de rappel, elle a seulement besoin de notifier la fonction de rappel pour démarrer l'exécution après avoir obtenu le statut résolu ou rejeté.

weight Utilisation de base

→ Créer un différé

var monPremierDeferred = $q.defer();

Ici, pour le myFirstDeferred différé, le statut est en attente. Ensuite, lorsque la méthode asynchrone est exécutée avec succès, le statut est résolu. Lorsque la méthode asynchrone échoue, le statut est rejeté.

→ Résoudre ou rejeter ce problème

Supposons qu'il existe une telle méthode asynchrone : async(succès, échec)

async(function(value){
  myFirstDeferred.resolve(value);
}, function(errorReason){
  myFirstDeferred.reject(errorReason);
})
 
Copier après la connexion

Dans AngularJS, la résolution et le rejet de $q ne dépendent pas du contexte, et peuvent s'écrire grossièrement comme ceci :

async(myFirstDeferred.resolve, myFirstDeferred.reject);

→ Utiliser la promesse en différé

var myFirstPromise = myFirstDeferred.promise;

myFirstPromise
  .then(function(data){
  
  }, function(error){
  
  })
 

Copier après la connexion

le différé peut avoir plusieurs promesses.

var anotherDeferred = $q.defer();

anotherDeferred.promise
  .then(function(data){
  
  },function(error){
  
  })
  
//调用异步方法
async(anotherDeferred.resolve, anotherDeferred.reject);

anotherDeferred.promise
  .then(function(data){
  
  }, function(error){
  
  })
 

Copier après la connexion

Ci-dessus, si la méthode asynchrone async est exécutée avec succès, les deux méthodes de réussite seront appelées.

→ Enveloppez généralement les méthodes asynchrones dans une fonction

function getData(){
  var deferred = $q.defer();
  async(deferred.resolve,deferred.reject);
  return deferred.promise;
}

//deferred的promise属性记录了达到resolved, reject状态所需要执行的success和error方法
var dataPromise = getData();
dataPromise
  .then(function(data){
    console.log('success');
  }, function(error){
    console.log('error');
  })
 

Copier après la connexion

Comment écrire si vous vous concentrez uniquement sur la fonction de rappel de réussite ?

dataPromise
  .then(function(data){
    console.log('success');
  })
 

Copier après la connexion

Comment écrire si vous vous concentrez uniquement sur la fonction de rappel d'erreur ?

dataPromise
  .then(null, function(error){
    console.log('error');
  })
  
或

dataPromise.catch(function(error){
  console.log('error');
})
 

Copier après la connexion

Et si le rappel renvoie le même résultat, quel que soit le succès ou l'échec ?

var finalCallback = function(){
  console.log('不管回调成功或失败都返回这个结果');
}
Copier après la connexion

dataPromise.then(finalCallback, finalCallback);

ou

dataPromise.finally(finalCallback);
■ Chaîne de valeur

Supposons qu'il existe une méthode asynchrone qui renvoie une valeur en utilisant deferred.resolve.

function async(value){
  var deferred = $q.defer();
  var result = value / 2;
  deferred.resolve(result);
  return deferred.promise;
}
 

Copier après la connexion

Puisque ce qui est rendu est une promesse, nous pouvons continuer de temps en temps.

var promise = async(8)
  .then(function(x){
    return x+1;
  })
  .then(function(x){
    return x*2;
  })
  
promise.then(function(x){
  console.log(x);
}) 
Copier après la connexion

Ci-dessus, la valeur de la résolution devient le paramètre réel de chaque chaîne.

Enchaînement de promesses

function async1(value){
  var deferred = $q.defer();
  var result = value * 2;
  deferred.resolve(result);
  return deferred.promise;
}

function async2(value){
  var deferred = $q.defer();
  var result = value + 1;
  deferred.resolve(result);
  return deferred.promise;
}

var promise = async1(10)
  .then(function(x){
    return async2(x);
  })
  
promise.then(function(x){
  console.log(x);
}) 
 

Copier après la connexion

Bien sûr, une façon plus lisible de l'écrire est :

function logValue(value){
  console.log(value);
}

async1(10)
  .then(async2)
  .then(logValue);
 

Copier après la connexion

La valeur de retour de la méthode async1 devient le paramètre réel de la méthode success dans la méthode then.

Du point de vue de la détection des exceptions, vous pouvez également écrire comme ceci :

async1()
  .then(async2)
  .then(async3)
  .catch(handleReject)
  .finally(freeResources);
 

Copier après la connexion

weight $q.reject(raison)

L'utilisation de cette méthode peut faire apparaître le différé en état d'erreur et donner la raison de l'erreur.

var promise = async().then(function(value){
  if(true){
    return value;
  } else {
    return $q.reject('value is not satisfied');
  }
})

Copier après la connexion

■ $q.quand(valeur)

Renvoyer une promesse avec de la valeur.

function getDataFromBackend(query){
  var data = searchInCache(query);
  if(data){
    return $q.when(data);
  } else {
    reutrn makeAasyncBackendCall(query);
  }
}

Copier après la connexion

weight $q.all(promisesArr)

Attendez que toutes les promesses soient exécutées.

var allPromise = $q.all([
  async1(),
  async2(),
  ...
  asyncN();
])

allProise.then(function(values){
  var value1 = values[0],
    value2 = values[1],
    ...
    valueN = values[N];
    
  console.log('all done');
})
Copier après la connexion

Ce qui précède est le contenu détaillé de cet article. J'espère qu'il sera utile à l'étude de chacun.

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal