大家都知道JS语言的执行方式为单线程,也就是说在执行JS语句的时候,不能同时执行多个语句,遇到一些执行时间较长的语句的时候,比如网络请求等,这种同步方式显然不是很好的处理方案。将这样一些比较耗时的语句异步处理,在用户体验上会好很多,异步解决方案有多种,其中一种即为Promise。
Promise为一个对象,我们可以通过构造函数来创建一个实例,构造函数接受一个函数作为参数。
var p = new Promise(function q(){})
Promise对象有三种状态,分别为pending,fulfilled和rejected。pending状态为其初始状态,fulfilled为已成功状态,rejected为已失败状态。pending状态可以变为fulfilled或rejected,并且状态只可以改变一次,比如pending变为fulfilled之后,就无法再变为rejected了。举个例子:
var p = new Promise(function q(resolve,reject){
resolve(1);
})
上面的例子中,resolve和reject为Promise内设的两个函数,并不需要我们定义,当调用resolve函数时,Promise状态从pending变为fulfilled,当调用reject的时候,则从pending变为rejected。注意,这里的resolve和reject可以改名,比如用a和b也可以,只要位置相对应上即可。
当Promise对象的状态发生改变后,就会执行相应的回调函数。我们是把这些回调函数放在Promise对象的then,catch,finally等方法里。比如:
p.then(func1,func2);
func1为状态pending变为fulfilled之后的回调,func2为状态pending变为rejected之后的回调,我们也可以换一种写法,即:
p.then(func1).catch(func2);
当状态变为fulfilled时,执行func1。如果变为rejected,则执行func2。举个简单例子:
var p = new Promise(function q(resolve,reject){
reject(1);
})
p.then(function func1(){console.log(2)}).catch(function func2(a){console.log(a)});
结果输出1。在该例中,创建实例时,调用reject函数,该函数传入了一个参数,然后Promise对象状态从pending变为rejected,catch方法中的func2函数被调用,并且该函数接收reject函数传递过来的参数,最后将该参数即1打印出来 。
var p = new Promise(function q(resolve,reject){
reject(1);
resolve('a');
})
p.then(function func1(){console.log('a')}).catch(function func2(a){console.log(a)});
在上面的例子中,打印输出为1。我们可以看到Promise对象状态从pending变为rejected之后,是无法再变为fulfilled的。
Promise对象还有一个常用的finally方法,不管状态pending是变为fulfilled还是rejected,都会触发该方法。举个例子:
var p = new Promise(function q(resolve,reject){
reject(1);
resolve('a');
})
p.then(function func1(){console.log('a')}).catch(function func2(a){console.log(a)}).finally(function func3(){console.log('b')});
打印出来结果如上,状态pending变成rejected之后,先调用了catch方法,然后是finally方法。
本文如有错误之处,欢迎指正。以上仅简要介绍了Promise的部分知识,后续也会再补充,敬请期待。