首页 > 代码库 > 翻译:JavaScript Promises and AngularJS $q Service
翻译:JavaScript Promises and AngularJS $q Service
翻译:JavaScript Promises and AngularJS $q Service
原文:http://www.webdeveasy.com/javascript-promises-and-angularjs-q-service/
原文时间:2014年9月30号
一个promise(延缓)是处理异步开发简单而强大的方法。CommonJS 维基百科列出了 几个promise模式的实施提议。AngularJS自己的promise实现方法是受kris Kowal‘s Q的方法启发的。在这篇文章中我会介绍promises,它的目的和怎么通过AngularJS $q的promise服务开发的教程。
Promise(延缓)目的
在JavaScript中,异步方法通常通过调用回调方法来实现成功或失败的处理。比如说浏览器的地理位置api,获取地理坐标时就需要成功或者失败的回调方法。
function success(position) { var coords = position.coords; console.log(‘Your current position is ‘ + coords.latitude + ‘ X ‘ + coords.longitude);}function error(err) { console.warn(‘ERROR(‘ + err.code + ‘): ‘ + err.message);}navigator.geolocation.getCurrentPosition(success, error);
另一个例子就是xhr请求(ajax请求),它有一个onreadystatechange回调方法,当readyState改变时就会调用它。
var xhr = new window.XMLHttpRequest();xhr.open(‘GET‘, ‘http://www.webdeveasy.com‘, true);xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { console.log(‘Success‘); } }};xhr.send();
Javascript中还有许多其他的异步例子,下面讨论麻烦的多个异步方法运行。
串行(无尽金字塔)
假设现在又N种异步方法需要串行运行:async1(success, failure)
, async2(success, failure)
, …, asyncN(success, failure),一个接一个直到成功,每个方法都有成功和失败的回调,那么代码就是这样:
async1(function() { async2(function() { async3(function() { async4(function() { .... .... .... asyncN(null, null); .... .... .... }, null); }, null); }, null);}, null);
这就是著名的回调金字塔(callback pyramid of doom)。虽然还有更好的写法(把回调流分隔成函数),但是这种方式还是很难读懂和维护。
并行
假设我们有N个异步方法,async1(success, failure)
, async2(success, failure)
, …, asyncN(success, failure)
,我们需要让他们并行运行,再在最后弹出一个消息。每个方法都有成功和失败的回调,那么代码就是这样:
var counter = N;function success() { counter --; if (counter === 0) { alert(‘done!‘); }}async1(success);async2(success);........asyncN(success);
我们声明了一个变量counter,让它的值为N,每当一个方法成功了,就减一,然后检测是否为零,也就是是否执行到最后一个了。这种方法使用起来既麻烦又不利于维护,特别是当每个异步方法还有参数要传到success()方法里的时候,那样我们还要保存每次运行的结果。
在上面两个例子里,在一个异步操作过程中,我们必须要指定成功的回调。也就是说,当我们用回调时,异步操作的继续需要一个引用,但是它的下一步操作也许是与自己无关的。这就导致了很难重复使用和测试的紧密耦合模块和服务。
翻译:JavaScript Promises and AngularJS $q Service