摘要:一旦非同步操作完成,就调用指定的回调函数,并总是返回一个对象,方便链式调用。方法接受两个回调函数作为参数,第一个参数是成功时的回调,第二个是失败时的回调。方法,方法是定义在原型对象上的,作用是为对象添加回调函数。
先上一个大家比较熟悉的例子;
以前我们写jquery ajax请求的时候,都是这样写:
$.ajax({ url: "test.json", success: function(){ alert("hello world!"); }, error:function(){ alert("error"); } });
后来呢在jquery1.7版本后,我们开始这样写:
$.ajax("test.json") .done(function(){ alert("hello world!"); }) .fail(function(){ alert("error"); });
很明显,更改后的代码更易懂易读了。
这个是jquery的deferred对象,jquery deferred对象就是jQuery对Promises的实现,还其他有很多实现了promises的库供开发者可用。 像微软的 WinJS.Promise, when.js, q, 和dojo.Deferred,它们暴露的都是deferred对象。Promise也已经纳入了ES6,对于jQuery实现Promises我们暂时就不讲了,今天的目的是Promise。
其实呢,Promise就是一个对象,它是用来实现异步操作的,它可以让异步代码书写起来更优雅,更便于阅读。
Promise的特性:
1、Promise对象有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败),只有异步操作结果可以改变当前状态,其他操作不能改变状态,Promise对象的状态只能从“进行中”改为“已完成”或者从“进行中”改为“失败”。
2、Promise对象的then方法,就是用来指定回调函数。一旦非同步操作完成,就调用指定的回调函数,并总是返回一个promise对象,方便链式调用。而且同一个promise的then可以调用多次。
3、then方法接受两个回调函数作为参数,第一个参数是成功Resolved时的回调,第二个是失败Reject时的回调。第二个参数是可以选的,同时,then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。
我们现在用promise来组织一下代码。
var sleep = function (time) { return new Promise(function (resolve, reject) { console.log("test123"); setTimeout(function () { resolve("test"); }, time); }) }; (function(){ console.log("start"); sleep(3000) .then(function(data){ console.log(data); return sleep(5000);}) .then(function(data){ console.log(data); console.log("end"); }) })();
上面代码中,sleep方法返回一个Promise实例,表示一段时间以后才会发生的结果。首先输出‘start’,然后,sleep执行后,3秒后返回“test”,触发then方法绑定的回调函数,输出回调返回值“test”,又return sleep(5000),这样第一个then的返回值,就是第二个的参数,再次执行sleep,5秒后返回‘test’,输出‘test’、"end";
好像没有什么大不了的,promises的真正强大之处在于多重的链接,在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了:它有个缺点就是链过长以后,满屏幕的then,傻傻分不清业务到底干啥了,
Promise的 api1、Promise.resolve()
2、Promise.reject()
3、Promise.prototype.then()
4、Promise.prototype.catch()
5、Promise.all() // 所有的都有完成,相当于 且
6、Promise.race() // 完成一个即可,相当于 或
1、Promise.resolve()的作用将现有对象转为Promise对象resolvedl;
Promise.resolve("test")==new Promise(resolve=>resolve("test"))
2、Promise.reject()也是返回一个Promise对象,状态为rejected;
let p=Promise.reject("error") == let p=new Promise((resolve,reject)=>reject("error")); p.catch(data=>{ console.log(data); })
生成一个Promise对象的实例对象p,抛出错误,状态就会变为Rejected,调用p.catch()指定的回调函数。
3、.then()方法,then方法是定义在原型对象Promise.prototype上的,作用是为Promise 对象添加回调函数。
let p=new Promise(resolve=>resolve("hello")); p.then((resolve,reject)=>{ console.log(resolve); }).then(function(){ console.log("zhangsan"); })
then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。 可以使用链式操作,指定多个then(),依次执行,上面的代码输出结果:’hello‘,"zhangsan"
4、.catch():发生错误的回调函数,同样,catch方法也是定义在原型对象Promise.prototype上的,事例同Promise.reject()的例子。注:如果Promise的状态已经变为resolved,再抛出错误是无效的。
var p = new Promise(function(resolve, reject) { resolve("success"); reject("fail"); }); p.then(function(value) { console.log(value) }) .catch(function(error) { console.log(error) });
输出结果:success;
5、Promise.all()的作用是同时执行多个实例,同步并行,且所以的实例都返回resolve状态,Promise才会改变为resolve状态,其中一个为rejected,promise的状态就是rejected;
注:Promise.all 方法的参数可以不是数组,但是必须是一个Iterator接口对象,且返回promise实例,否则报错:error:TypeError: [object Promise] is not iterable!
let p1 =new Promise(function(resolve,reject){ resolve(1); }); let p2 = new Promise(function(resolve,reject){ resolve(2); }); let p3 = new Promise(function(resolve,reject){ // reject(); resolve(3); }); Promise.all([p1, p2, p3]).then(function (results) { console.log("success:"+results); }).catch(function(r){ console.log("error"); console.log(r); });
上面代码输出:success:1,2,3;
把 p3方法改为返回 reject();输出结果是:error;
6、Promise.race()的作用也是同时执行多个实例,只要有一个实例改变状态,Promise就改为那个实例所改变的状态;
let p1 =new Promise(function(resolve,reject){ setTimeout(function(){ reject(1); },3000) }); let p2 = new Promise(function(resolve,reject){ setTimeout(function(){ resolve(2); },1000) }); Promise.race([p1, p2]).then(function (results) { console.log("success:"+results); }).catch(function(results){ console.log("error:"+results); }); 输出:success: 2;
上面代码p2首先执行完毕,改变状态为resolve,所以promise的状态被改为resolve;
我们把p1的时间改为1000,p2改为3000,也就是说p1先执行完毕,promise的状态也被改变为reject,输出:error:1
如果想深入学习,可以看一下阮一峰的《ES 6标准入门》的Promise部分http://es6.ruanyifeng.com/#do...,很详细的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/81790.html
摘要:三是控制反转控制权在其他人的代码上,假如异步函数是别人提供的库,我们把回调函数传进去,我们并不能知道异步函数在调用回调函数之外做了什么事情。错误捕捉相比回调函数的错误无法在外部捕捉的问题,能够为一连串的异步调用提供错误处理。 前言 《JS异步编程之 callback》一文我们了解了JS 是基于单线程事件循环的概念构建的,回调函数不会立即执行,由事件轮询去检测事件是否执行完毕,当执行完有...
摘要:到这里,我已经发出了一个请求买汉堡,启动了一次交易。但是做汉堡需要时间,我不能马上得到这个汉堡,收银员给我一个收据来代替汉堡。到这里,收据就是一个承诺保证我最后能得到汉堡。 同期异步系列文章推荐谈一谈javascript异步javascript异步中的回调javascript异步之Promise.all()、Promise.race()、Promise.finally()javascr...
摘要:所以,函数的一个重要实际意义就是用来处理异步操作,改写回调函数。表示在这里等待异步操作返回结果,再继续执行。 JS异步之Promise,Generator,Async Promise 解决的问题:回调地狱 Promise规范: promise有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected).Promise的状态只能从...
摘要:所以,函数的一个重要实际意义就是用来处理异步操作,改写回调函数。表示在这里等待异步操作返回结果,再继续执行。 JS异步之Promise,Generator,Async Promise 解决的问题:回调地狱 Promise规范: promise有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected).Promise的状态只能从...
摘要:所以,函数的一个重要实际意义就是用来处理异步操作,改写回调函数。表示在这里等待异步操作返回结果,再继续执行。 JS异步之Promise,Generator,Async Promise 解决的问题:回调地狱 Promise规范: promise有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected).Promise的状态只能从...
阅读 2452·2021-11-24 09:39
阅读 3496·2019-08-30 15:53
阅读 574·2019-08-29 15:15
阅读 2877·2019-08-26 13:23
阅读 3188·2019-08-26 10:48
阅读 615·2019-08-26 10:31
阅读 730·2019-08-26 10:30
阅读 2303·2019-08-23 18:32