AngularJs $q service

Introducción

Asynchronous We will get a result from an action at some point in the future.

$q service

A service that helps you run functions asynchronously, and use their return values (or exceptions) when they are done processing.

Implementación 1
$q(function(resolve, reject, notify){
  ...
  var ok = ...
  resolve(ok);
  ...
  var error = ...
  reject(error)
  ...
  var notify = ...
  notify(error)
}
Implementación 2
var deferred = $q.defer();
...
var ok = ...
deferred.resolve(ok);
...
var error = ...
deferred.reject(error);
...
var notify = ...
deferred.notify(error);
Ejemplo Implementación 1
var app = angular.module("app", []);

app.controller("promiseController", function($scope, $q) {

  function okToGreet(name){
    return (Math.random() < 0.2) ? false : true;
  };
  
  function asyncGreet(name) {
    // perform some asynchronous operation, resolve or reject the promise when appropriate.
    return $q(function(resolve, reject) {
      setTimeout(function() {
        if (okToGreet(name)) {
          resolve('Hello, ' + name + '!');
        } else {
          reject('Greeting ' + name + ' is not allowed.');
        }
      }, 1000);
    });
  }

  var promise = asyncGreet('Robin Hood');
  promise.then(function(greeting) {
    alert('Success: ' + greeting);
  }, function(reason) {
    alert('Failed: ' + reason);
  });
});
Ejemplo Implementación 2
var app = angular.module("app", []);

app.controller("promiseController", function($scope, $q) {

  function okToGreet(name){
    return (Math.random() < 0.2) ? false : true;
  };
  
  function asyncGreet(name) {
    var deferred = $q.defer();

    setTimeout(function() {
      deferred.notify('About to greet ' + name + '.');

      if (okToGreet(name)) {
        deferred.resolve('Hello, ' + name + '!');
      } else {
        deferred.reject('Greeting ' + name + ' is not allowed.');
      }
    }, 1000);

    return deferred.promise;
  }

  var promise = asyncGreet('Robin Hood');
  promise.then(function(greeting) {
    alert('Success: ' + greeting);
  }, function(reason) {
    alert('Failed: ' + reason);
  }, function(update) {
    alert('Got notification: ' + update);
  });
});
Chaining Promises

Because calling the then method of a promise returns a new derived promise, it is easily possible to create a chain of promises:

  var promiseA = asyncGreet('Robin Hood').then(function(greeting) {
    alert('Success: ' + greeting);
    return true;
  }, function(reason) {
    alert('Failed: ' + reason);
    return false;
  });
  
  var promiseB = promiseA.then(
    function(response) { 
      if(true) alert("Welcome")
      else alert("Bye")
    },
    function(reason) { alert(reason); }
  );

Encadenamiento parámetro - respuesta
El encadenamiento de parámetros - respuesta tiene un comportamiento errático en angular, el siguiente código debería funcionar pero no me funcionó al ejecutarlo dentro de un servicio AngularJS. Me daba error de metodos no definidos.

//promesa 1
var promise1 = function(param1){
  ...
  return $q.when(response1);
}

//promesa 2
//"param2" tiene la misma estructura que "response1"
var promise2 = function(param2){
  ...
  return $q.when(response2);
}


var exec = function(){ 
  self.promise1().then(promise2).then(
    function(response2){ ... }
  );
);
$q.all

Combines multiple promises into a single promise that is resolved when all of the input promises are resolved.

* If you provide them as an array, then the values will be available as an array with the same corresponding order of the promises array.

var promises = [promiseAlpha(), promiseBeta(), promiseGamma()];

$q.all(promises).then(
  function(response){
    console.log(response[0]); // value alpha
    console.log(response[1]); // value beta
    console.log(response[2]); // value gamma
    console.log("complete");
  }
});


//if you provide an object literal to all(), the values are attached to an object with the same corresponding property names
var promises = {alpha: promiseAlpha(), beta: promiseBeta(), gamma: promiseGamma()}

$q.all(promises).then(
  function(response){
    console.log(response.alpha); // value alpha
    console.log(response.beta);  // value beta
    console.log(response.gamma); // value gamma
    console.log("complete");
  }
});


//si utilizamos un array de promesas vacio se considera como resuelta
var promises = [] 
$q.all(promises).then((values) => {
  console.log("complete");
});
$q.when
var deferred = $q.defer();
deferred.resolver("respuesta");
return deferred.promise;

Es lo mismo que:

return $q.when("respuesta");
Using promises in angular views

Podemos asignar directamente la respuesta de una promesa a una variable del $scope y se mostraran los resultados en el html

angular.module('myModule', []).controller('HelloCtrl', function($timeout, $q, $scope) {
  var getMessages = function() {
    var deferred = $q.defer();
  
    $timeout(function() {
       deferred.resolve(['Hello', 'world']);
    }, 10000);
  
      return deferred.promise;
  };
   

  $scope.messages = getMessages().then(
    function(response){ return response; }
  });

<br /> <body ng-app="myModule" ng-controller="HelloCtrl"></p> <h1>Messages</h1> <ul> <li ng-repeat="message in messages">{{ message }}</li> </ul> <p></body><br />
Fuente
https://docs.angularjs.org/api/ng/service/$q
http://www.martin-brennan.com/using-q-all-to-resolve-multiple-promises/
http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/
http://taoofcode.net/promise-anti-patterns/

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *