Servicio $ q en angularJS

                     Reimpreso de http://blog.csdn.net/renfufei/article/details/19174015

Descripción

Nota del traductor : vi un muy buen artículo. Si está interesado, puede consultar:  Promesas y programación asincrónica de Javascript  , que contiene especificaciones de Promesas y escenarios de uso.

Como se usa para manejar la programación asincrónica, hay dos tipos principales de JS en el navegador: solicitudes setTimeout y Ajax. El uso de promesas es muy similar a las devoluciones de llamadas de éxito y fracaso de las solicitudes Ajax.


Esta implementación prometida / diferida está inspirada en   el documento de recomendación Q CommonJS Promise de Kris Kowal que  utiliza promesas como interfaz para interactuar con objetos de resultados de ejecución asincrónicos, que pueden completarse en un tiempo específico o posible No se puede completar (como tiempo de espera, error, intercepción, etc.).

Desde la perspectiva del manejo de errores, las API diferidas  y prometedoras  son similares a  probar , atrapar y lanzar  programación síncrona para programación asíncrona .
[javascript]   ver copia simple  
  1. // Para fines de demostración, aquí asumimos que las referencias `$ q`,` scope` y `okToGreet` están disponibles en el entorno de ejecución actual  
  2. // (Por ejemplo, se han inyectado o pasado como parámetros).  
  3.    
  4. función  asyncGreet (nombre) {  
  5.   var  diferido = $ q.defer ();  
  6.    
  7.   setTimeout ( function () {  
  8.     // Debido a que esta función se ejecuta de forma asíncrona en el bucle de eventos futuros,  
  9.     // Necesitamos ajustar el código en una llamada $ apply para observar correctamente el cambio de modelo  
  10.     alcance. $ apply ( function () {  
  11.       deferred.notify ( 'saludo pronto'  + nombre +  '.' );  
  12.    
  13.       if  (okToGreet (nombre)) {  
  14.         deferred.resolve ( 'Hola,'  + nombre +  '!' );  
  15.       }  más  {  
  16.         deferred.reject ( 'Rechazar saludo'  + nombre +  '.' );  
  17.       }  
  18.     });  
  19.   }, 1000);  
  20.    
  21.   retorno  diferido.promise;  
  22. }  
  23.    
  24. var  promise = asyncGreet ( 'Pequeño desierto' );  
  25. promise.then ( function (saludo) {  
  26.   alerta ( 'Éxito:'  + saludo);  
  27. },  función (razón) {  
  28.   alerta ( 'Pájaro fallido:'  + razón);  
  29. },  función (actualización) {  
  30.   alerta ( 'Notificación recibida:'  + actualización);  
  31. });  

El efecto de introducir esta complejidad adicional puede no ser obvio al principio. Los beneficios se ven cuando se comprometen las promesas y las API diferidas, consulte:   https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md
Además, la API de promesas permite a quienes tienen devoluciones de llamada tradicionales (CPS) Una combinación que es difícil de lograr en el método. Para obtener más información, consulte la  documentación de Q  , especialmente la sección sobre la combinación de serie y paralelo.

Interfaz de retardo | API diferida

通过调用  $q.defer() 可以构建一个新的 deffered 实例。
deffered 对象用来将 Promise 实例与 标记任务状态(执行成功还是不成功)的 API 相关联。

deffered 对象的方法

  • resolve(value) ——传入 value 解决派生的 promise。 如果 value 是一个通过 $q.reject 构造的拒绝对象(rejection) , 该promise 将被拒绝。
  • reject(reason) ——拒绝派生的promise,并提供原因 。 这相当于通过 $q.reject构造的拒绝对象(rejection)作为参数传递给 resolve。
  • notify(value)  ——在 promise 执行的过程中提供状态更新。 这在 promise 被解决或拒绝之前可能会被多次调用。

deffered 对象的属性

promise – {Promise}  —— 与延迟(deferred)相关联的 promise 对象。

承诺 接口 | Promise API

当创建 deferred 实例时会创建一个新的 promise 对象,并可以通过   deferred.promise  得到该引用。
promise 对象的目的是在 deferred 任务完成时,允许感兴趣的部分取得其执行结果。

promise 对象的方法

  • then(successCallback, errorCallback, notifyCallback) ——不管 promise 是被处理还是被拒绝, 一旦结果可用,then 就会尽快地异步调用 成功/错误 回调函数 只要结果是可用的。 调用回调函数时传递单个参数: 结果 或拒绝的理由。 此外,notify 回调可能被调用 0到多次,以提供 提供一个进度指示,之前承诺解决或拒绝。
           这个方法 返回一个新的promise 对象, 根据 successCallback , errorCallback的返回值进行解决或拒绝 。 它还通过 notifyCallback 方法的返回值进行通知。 promise 不能从notifyCallback方法得到解决或拒绝 。
  • catch(errorCallback) —— promise.then(null, errorCallback) 的快捷方式
  • finally(callback) ——让你可以观察到一个 promise 是被执行还是被拒绝, 但这样做不用修改最后的 value值。 这可以用来做一些释放资源或者清理无用对象的工作,不管promise 被拒绝还是解决。 更多的信息请参阅完整文档规范.
            因为在 ES3版本的JavaScript中 finally 是一个保留字关键字,不能作为属性名,为了适配 IE8,您需要使用  promise['finally'](callback) 这种形式来调用该方法。

promise 链 | Chaining promises

因为调用一个 promise 的 then 方法返回一个新的派生 promise实例,所以构建promises链也是很容易的:
[javascript]  view plain  copy
  1. promiseB = promiseA.then(function(result) {  
  2.   return result + 1;  
  3. });  
  4.    
  5. // promiseB 将会在处理完 promiseA 之后立刻被处理,  
  6. // 并且其  value值是promiseA的结果增加1  
我们可以创建任意长度的promise链;因为一个promise可以被另一个promises处理(进一步推迟解决完成时间),所以在promise链上的任意一点进行 暂停/推迟解决 都是可行的。 这使得实现功能强大的APIs 成为现实,例如   $http  的响应拦截器。

Kris Kowal's Q 与 $q 之间的区别

主要区别有两点:
  • Angular中的$q 集成了 ng.$rootScope.Scope  Scope模型观察机制,这意味着对models 的解决或拒绝速度将会更快,避免不必要的浏览器重绘(会导致UI闪烁)。
  • Q 比 $q拥有更多的功能特性,但带来的是代码字节数的增加。 $q 很轻量级,但包含了一般异步任务所需的所有重要功能。

     测试

[javascript]  view plain  copy
  1. it('should simulate promise', inject(function($q, $rootScope) {  
  2.   var deferred = $q.defer();  
  3.   var promise = deferred.promise;  
  4.   var resolvedValue;  
  5.    
  6.   promise.then(function(value) { resolvedValue = value; });  
  7.   expect(resolvedValue).toBeUndefined();  
  8.    
  9.   // 模拟 promise 的 resolving  
  10.   deferred.resolve(123);  
  11.   // 注意 'then' function 不是同步调用的.  
  12.   // 因为我们想要  promise API 一直是异步的(async),  
  13.   // 不管是在同步调用还是异步调用中都是如此.  
  14.   expect(resolvedValue).toBeUndefined();  
  15.    
  16.   // 使用 $apply()将 promise resolution 传递到 'then' functions .  
  17.   $rootScope.$apply();  
  18.   expect(resolvedValue).toEqual(123);  
  19. }));  

依赖关系 | Dependencies

$rootScope 

方法 | Methods

all(promises)

结合多个promises为单个promise,在所有输入的promise都处理之后,组合之后的promise才会处理完成。
  • 参数: promises
  • 类型: Array.<Promise>/Object.<Promise>
  • 描述: promises的数组或者引用
  • 返回: Promise 返回单个的 promise,将与一个数组解决/散列值, 每个值对应于在相同的索引/关键的承诺 承诺 /散列数组。 如果任何承诺解决排斥,这产生的承诺将被拒绝 拒绝相同的值。

defer()

创建一个 递延 对象代表一个将来完成任务。
  • 返回  Deferred 返回一个新实例的Deferred。

reject(reason)

创建一个指定拒绝原因的promise. 此api应该用于在一个promises链中进行拒绝。 如果你正在处理promise 链中的最后一个promise,你不需要担心。

把  deferreds/promises 与我们熟悉的的 try/catch/throw行为进行对比,可以认为 reject 相当于 JavaScript 中的throw 关键字。 这也意味着如果你通过一个 promise 的 error回调,  “catch”了一个错误 ,你想要指明当前的承诺已经执行出错了,就必须重新抛出一个“附带了错误信息,拒绝通过的reject” 。
[javascript]  view plain  copy
  1. promiseB = promiseA.then(function(result) {  
  2.   // success: 此处可以执行某些操作,然后直接使用原有的result,  
  3.   // 或者对result进行操作,来处理接下来的promiseB  
  4.   return result;  
  5. }, function(reason) {  
  6.   // error: handle the error if possible and  
  7.   //        resolve promiseB with newPromiseOrValue,  
  8.   //        否则转向拒绝 promiseB 的分支  
  9.   if (canHandle(reason)) {  
  10.    // 处理错误和恢复  
  11.    return  newPromiseOrValue;  
  12.   }  
  13.   devuelve  $ q.reject (motivo);  
  14. });  
  • Parámetro:  razón
  • Tipo: *
  • Descripción:  Constante, mensaje, excepción  u objeto que representa el motivo del rechazo.
  • Devolución:  Promesa     devolvió una promesa, que ha sido rechazada por razones.

cuando (valor)

Envuelva un objeto (probablemente un valor o una promesa que pueda hacer un tercero) en una promesa $ q. Esto es útil cuando no está seguro de si el objeto que se está procesando es una promesa. Es posible que el objeto provenga de una fuente no confiable.
  • Parámetro:  valor
  • Tipo: *
  • Descripción: El valor de la promesa.
  • Volver  promesa     promesa después de que el paquete devuelve un valor de la / o la promesa pasado



Publicado 7 artículos originales · ganó 5 · visitado 4120

Supongo que te gusta

Origin blog.csdn.net/blue_heart_/article/details/78772539
Recomendado
Clasificación