Buscar..


Usando $ q.all para manejar múltiples promesas

Puede usar la función $q.all para llamar a un método .then después de que una serie de promesas se haya resuelto con éxito y recuperar los datos con los que se resolvieron.

Ejemplo:

JS:

 $scope.data = []

 $q.all([
    $http.get("data.json"),
    $http.get("more-data.json"),
    ]).then(function(responses) {
      $scope.data = responses.map((resp) => resp.data);
    });

El código anterior se ejecuta $http.get 2 veces para los datos en archivos JSON locales, cuando ambos get método completo que resuelven sus promesas asociadas, cuando se resuelvan todas las promesas de la matriz, la .then método comienza con las dos promesas de datos dentro de las responses argumento de la matriz.

Luego, los datos se asignan para que se puedan mostrar en la plantilla, luego podemos mostrar

HTML:

<ul>
   <li ng-repeat="d in data">
      <ul>
         <li ng-repeat="item in d">{{item.name}}: {{item.occupation}}</li>
      </ul>
   </li>
</ul>

JSON:

[{
  "name": "alice",
  "occupation": "manager"
}, {
  "name": "bob",
  "occupation": "developer"
}]

Usando el constructor $ q para crear promesas

La función constructora $q se utiliza para crear promesas a partir de API asíncronas que utilizan devoluciones de llamada para devolver resultados.

$ q (función (resolver, rechazar) {...})

La función constructora recibe una función que se invoca con dos argumentos, resolve y reject que son funciones que se utilizan para resolver o rechazar la promesa.

Ejemplo 1:

function $timeout(fn, delay) {
    return = $q(function(resolve, reject) {
         setTimeout(function() {
              try {
                 let r = fn();
                 resolve(r);
              } 
              catch (e) {
                 reject(e);
              }
         }, delay);
     };
}
    

El ejemplo anterior crea una promesa de la API WindowTimers.setTimeout . El marco AngularJS proporciona una versión más elaborada de esta función. Para uso, vea la referencia de la API del servicio de tiempo de espera de AngularJS $ .

Ejemplo 2:

$scope.divide = function(a, b) {
    return $q(function(resolve, reject) {
      if (b===0) {
        return reject("Cannot devide by 0")
      } else {
        return resolve(a/b);
      }
    });
}

El código anterior que muestra una función de división promisificada, devolverá una promesa con el resultado o rechazará con una razón si el cálculo es imposible.

Luego puedes llamar y usar .then

$scope.divide(7, 2).then(function(result) {
    // will return 3.5
}, function(err) {
    // will not run
})

$scope.divide(2, 0).then(function(result) {
    // will not run as the calculation will fail on a divide by 0
}, function(err) {
    // will return the error string.
})

Operaciones diferidas usando $ q.defer

Podemos usar $q para aplazar las operaciones hacia el futuro mientras tenemos un objeto de promesa pendiente en el presente, mediante el uso de $q.defer Nosotros creamos una promesa que se resolverá o rechazará en el futuro.

Este método no es equivalente al uso del constructor $q , ya que usamos $q.defer a prometer una rutina existente que puede o no devolver (o alguna vez ha devuelto) una promesa.

Ejemplo:

var runAnimation = function(animation, duration) {
    var deferred = $q.defer();
    try {
        ...
        // run some animation for a given duration
        deferred.resolve("done");
    } catch (err) {
        // in case of error we would want to run the error hander of .then
        deferred.reject(err);
    }
    return deferred.promise;
}

// and then
runAnimation.then(function(status) {}, function(error) {})

  1. Asegúrese de devolver siempre un objeto deferred.promise o .then o de arriesgarse a un error al invocar .then

  2. Asegúrese de que siempre resuelve o rechaza su objeto diferido o, de lo .then posible que no se ejecute y corre el riesgo de una pérdida de memoria.

Usando promesas angulares con servicio $ q

$q es un servicio incorporado que ayuda a ejecutar funciones asíncronas y a usar sus valores de retorno (o excepción) cuando finalizan el procesamiento.

$q se integra con el mecanismo de observación del modelo $rootScope.Scope , lo que significa una propagación más rápida de la resolución o el rechazo en sus modelos y evita repinturas innecesarias en el navegador, lo que daría como resultado una interfaz de usuario parpadeante.

En nuestro ejemplo, llamamos a nuestra fábrica getMyData , que devuelve un objeto de promesa. Si el objeto se resolved , devuelve un número aleatorio. Si se rejected , devuelve un rechazo con un mensaje de error después de 2 segundos.

En fabrica angular

function getMyData($timeout, $q) {
  return function() {
    // simulated async function
    var promise = $timeout(function() {
      if(Math.round(Math.random())) {
        return 'data received!'
      } else {
        return $q.reject('oh no an error! try again')
      }
    }, 2000);
    return promise;
  }
}

Usando promesas de guardia

angular.module('app', [])
.factory('getMyData', getMyData)
.run(function(getData) {
  var promise = getData()
    .then(function(string) {
      console.log(string)
    }, function(error) {
      console.error(error)
    })
    .finally(function() {
      console.log('Finished at:', new Date())
    })
})

Para usar promesas, inyecte $q como dependencia. Aquí inyectamos $q en la fábrica getMyData .

var defer = $q.defer();

Una nueva instancia de aplazado se construye llamando a $q.defer()

Un objeto diferido es simplemente un objeto que expone una promesa, así como los métodos asociados para resolverla. Se construye utilizando la función $q.deferred() y expone tres métodos principales: resolve() , reject() y notify() .

  • resolve(value) : resuelve la promesa derivada con el valor.
  • reject(reason) - rechaza la promesa derivada con la razón.
  • notify(value) : proporciona actualizaciones sobre el estado de la ejecución de la promesa. Esto puede ser llamado varias veces antes de que la promesa sea resuelta o rechazada.

Propiedades

Se accede al objeto de promesa asociado a través de la propiedad de promesa. promise - {Promesa} - promete el objeto asociado con este aplazado.

Se crea una nueva instancia de promesa cuando se crea una instancia diferida y se puede recuperar llamando a deferred.promise .

El propósito del objeto de promise es permitir que las partes interesadas tengan acceso al resultado de la tarea diferida cuando se complete.

Métodos de promesa

  • then(successCallback, [errorCallback], [notifyCallback]) - Independientemente de cuándo se cumplió o se rechazará la promesa, luego llama a una de las devoluciones de llamada de éxito o error de forma asincrónica tan pronto como el resultado esté disponible. Las devoluciones de llamada se llaman con un solo argumento: el resultado o la razón de rechazo. Además, la devolución de llamada de notificación se puede llamar cero o más veces para proporcionar una indicación de progreso, antes de que se resuelva o se rechace la promesa.

  • catch(errorCallback) - abreviatura de promise.then (null, errorCallback)

  • finally(callback, notifyCallback) : le permite observar el cumplimiento o rechazo de una promesa, pero hacerlo sin modificar el valor final.

Una de las características más poderosas de las promesas es la capacidad de encadenarlas. Esto permite que los datos fluyan a través de la cadena y sean manipulados y mutados en cada paso. Esto se demuestra con el siguiente ejemplo:

Ejemplo 1:

// Creates a promise that when resolved, returns 4.
function getNumbers() {

  var promise = $timeout(function() {
    return 4;
  }, 1000);
  
  return promise;
}

// Resolve getNumbers() and chain subsequent then() calls to decrement
// initial number from 4 to 0 and then output a string.
getNumbers()
  .then(function(num) {
      // 4
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 3
      console.log(num);
      return --num;
  })
   .then(function (num) {
      // 2
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 1
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 0
      console.log(num);
      return 'And we are done!';
  })
  .then(function (text) {
      // "And we are done!"
      console.log(text);        
  });

Envuelva el valor simple en una promesa usando $ q.when ()

Si todo lo que necesita es envolver el valor en una promesa, no necesita usar la sintaxis larga como aquí:

//OVERLY VERBOSE
var defer;
defer = $q.defer();
defer.resolve(['one', 'two']);
return defer.promise;

En este caso puedes escribir:

//BETTER
return $q.when(['one', 'two']);

$ q.when y su alias $ q.resolve

Envuelve un objeto que podría ser un valor o una promesa (tercera parte) que luego se puede convertir en una promesa de $ q. Esto es útil cuando se trata de un objeto que puede o no ser una promesa, o si la promesa proviene de una fuente en la que no se puede confiar.

- AngularJS $ q Referencia de la API del servicio - $ q.when


Con el lanzamiento de AngularJS v1.4.1

También puede utilizar una resolve alias consistente con ES6

//ABSOLUTELY THE SAME AS when
return $q.resolve(['one', 'two'])

Evita el $ q diferido anti-patrón

Evita este Anti-Patrón

var myDeferred = $q.defer();

$http(config).then(function(res) {  
   myDeferred.resolve(res);
}, function(error) {
   myDeferred.reject(error);
});

return myDeferred.promise;

No hay necesidad de fabricar una promesa con $q.defer ya que el servicio $ http ya devuelve una promesa.

//INSTEAD
return $http(config);

Simplemente devuelva la promesa creada por el servicio $ http.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow