Open kuitos opened 9 years ago
原文写于 2015-01-25
先来说说什么是Promise吧
Promise是抽象异步处理对象以及对其进行各种操作的组件。 其详细内容在接下来我们还会学到,Promise并不是从JavaScript中发现的概念。 Promise最初被发现是在 E言語中, 它是基于并列/并行处理设计的一种编程语言。
简言之,Promise就是用于改善异步编程体验的一种编程模型,它提供一系列的api和方法论,让你能更优雅的解决异步编程中出现的一些问题。目前很多第三方框架或类库(如Angular和JQuery)都依照Promise/A+社区制定的规范做了相应的实现(JQuery基于历史原因很多地方与Promise规范不一致,so不建议通过JQuery源码学习Promise),最主要的是,Promise现在已经成为ES6的既定标准,目前部分高版本浏览器已原生支持Promise(后面有机会给出demo),所以我们还是很有必要来了解一下这到底是一个什么东西。
以前我们在处理一系列有依赖性的回调的时候,我们的代码是这样写的
step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); }); });
是的,就是一层层的回调嵌套,传说中的回调地狱 那么如果我们换成Promise的方式来实现呢
step1().then(step2).then(step3).then(step4)
效果显而易见,代码简单逻辑清晰,异步的回调嵌套写法变成了同步(本质上当然还是异步的)的写法看上去是不是优雅多了
目前,Angular基于现在流行的NodeJs异步流程控制库Q实现了一个微缩版的Q,它提供了一些最常用的规范的Promise API,并对外提供了$q这样一个service,这里我们介绍一下angular框架中主要有哪些api及相应的使用场景。(声明一点,angular中所有的ajax请求均返回promise)
Promise.then()
// 通常,我们处理多层顺序依赖的异步调用,我们会这样去写 $http.get().success(function (val1){ $http.get(val1).success(function (val2){ $http.get(val2).success(function (val3){ console.log(val3); }) }); }); // 当用Promise来处理时,写法会变成这样 function funcA(val1){ return $http.get(val1).suceess(function (val2){ return val2; }) } function funcB(val2){ return $http.get(val2).suceess(function (val3){ return val3; }) } function funcC(val3){ console.log(val3); } $http.get().then(funcA).then(funcB).then(funcC); // 很显然,使用了Promise方式代码可读性变的强很多
Deferred.resolve
// Deferred.resolve用于通知promise结果已经处理好,可以开始处理回调了 // 假设我们有这样一个业务,按钮点击时的处理逻辑依赖于另一个函数异步返回的数据,就像这样 var a; setTimeout(function(){ a = 10; },5000); dom.onclick = function(){ console.log(a); } // 我们总不能在onclick里轮询直到a被赋值吧。。 // 有了Promise一切变得简单 var defer = $q.defer(), a; setTimeout(function (){ defer.resolve(10); },5000); dom.onclick = function(){ defer.promise.then(function(a){ console.log(a); }); }
Deferred.reject
// 用法同deferred.resolve,只不过它调用之后会走失败回调 setTimeout(function(){ defer.reject(10); },5000); defer.promise.then(function successCb(a){ console.log(a+"success"); }, function errorCb(a){ console.log(a+"error"); }); // 5秒后打出 "10error"
Promise.all
// 这个api就非常给力了,假设我们有这样一个场景 // 页面上有A、B、C、D四块区域,其中A、B、C三块数据都是ajax获取的,D展示的数据需要综合A、B、C三个的数据 // 难道我们得在 A 的请求回调里调用 B ,然后再B请求回调里调C这样一层层嵌套,直到所有请求准备好了再去处理D ?这样整个页面在同一时间只能有一个请求发出,效率太低 // 可以这样写 $q.all([promiseA,promiseB,promiseC]).then(funcD) // 这样页面在同一时间会发出三个请求,当所有请求都好了之后再去处理D页面,代码不仅变得更清晰而且效率更高 最后介绍一下Promise.race([promises]),这个api angular并没有做实现,但是它已列入Promise/A+规范中,这里提一下 Promise.race([promises])与Promise.all([promises])类似,只不过Promise.all是与集运算,而Promise.race()是或集运算,当promises中有一个被resolve了就会继续后面的then
Promise.race
// 当promiseA或promiseB其中有一个被resolve,则后面funcT会被执行 // 使用场景有:进入一个页面时 当用户点击某个按钮或过5s 则展示某个提示,使用这个api会很方便 Promise.race([promiseA,promiseB]).then(funcT);
Javascript异步流程控制之Promise(1)-Angular $q简介
原文写于 2015-01-25
先来说说什么是Promise吧
简言之,Promise就是用于改善异步编程体验的一种编程模型,它提供一系列的api和方法论,让你能更优雅的解决异步编程中出现的一些问题。目前很多第三方框架或类库(如Angular和JQuery)都依照Promise/A+社区制定的规范做了相应的实现(JQuery基于历史原因很多地方与Promise规范不一致,so不建议通过JQuery源码学习Promise),最主要的是,Promise现在已经成为ES6的既定标准,目前部分高版本浏览器已原生支持Promise(后面有机会给出demo),所以我们还是很有必要来了解一下这到底是一个什么东西。
首先来看看,Promise的核心竞争力在哪
以前我们在处理一系列有依赖性的回调的时候,我们的代码是这样写的
是的,就是一层层的回调嵌套,传说中的回调地狱
那么如果我们换成Promise的方式来实现呢
效果显而易见,代码简单逻辑清晰,异步的回调嵌套写法变成了同步(本质上当然还是异步的)的写法看上去是不是优雅多了
目前,Angular基于现在流行的NodeJs异步流程控制库Q实现了一个微缩版的Q,它提供了一些最常用的规范的Promise API,并对外提供了$q这样一个service,这里我们介绍一下angular框架中主要有哪些api及相应的使用场景。(声明一点,angular中所有的ajax请求均返回promise)
使用场景
Promise.then()
Deferred.resolve
Deferred.reject
Promise.all
Promise.race