1,什么是Promise
Promise对象用于异步操作,它表示一个尚未完成且预计在未来完成的异步操作。
1.1,同步和异步的概念
JavaScript的执行环境是单线程;
所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程。
但实际上还有其他线程,如事件触发线程、ajax请求线程等。
1.1.1 同步
同步模式,一次只能执行一个任务,函数调用后需要等到函数执行结束,
返回执行结果,才能进行下一个任务。如果这个任务执行的时间较长。
就会导致线程阻塞。
var x = true; while(x); console.log("don't carry out"); //并不会执行这句
while是一个死循环,它会阻塞进程,因此后面的console并不会执行。
1.1.2 异步
异步与同步模式相反,可以一起执行多个任务。函数的调用不会立马返回执行结果。
如果A任务需要等待(如读取文件),可先执行B任务。等A任务结果返回再继续回调。
setTimeout(function(){ console.log('task A, asynchronous'); },0); console.log('Task B, synchronous'); -------output-------- task B, .... task A, ....
我们可以看到,定时器延时的时间明明是0,但是task A 还是比task B后执行。
原因是定时器是异步的,异步任务会在同步任务执行完之后才会执行。
因为同步任务阻塞了进程。
1.1.3 回调函数
异步,必须提到回调函数。
setTimeout里面的function就是回调函数。
可以理解为:执行完 调用的 函数。
回调函数不仅可以用于异步调用,一般的同步场景也可以回调。
同步:回调函数一般是最后执行;
异步:一段时间后执行或者不执行(没有达到执行条件)。
/* 同步回调 */ var fun1 = function( callback){ //do something console.log("before callback") ; (callback && typeof(callback) === 'function') && callback(); console.log("after callback"); } var fun2 = function (param){ // do something var start = new Date(); while( (new Date() - start) ) < 3000 { // delay 3000ms } console.log("I‘am callback"); } fun1(fun2); ------output----- before callback //after 3000ms I ' am callback //再执行同步回调 after callback
1.2 为什么使用Promise
Promise是基于异步操作的。
既然我们可以使用异步回调的进行异步操作,为什么还要使用Promise呢?
function sendRequest(url , param){ return new Promise(fiunctiuon (resolve,reject) { request (url , param, resolve, reject); }); } sendRequest('test.html' , ' ' ).then (function(data) { //异步操作成功后回调 console.log('请求成功,这是返回的数据:' , data); } function (error){ //异步操作失败的回调 console.log('sorry,请求失败了,这是失败信息:’) ,error); } );
上述的Promise 的简单用法;
我们可以看到Promise 的强大的之处是:多重链式调用;
sendRequest('test1.html', '').then(function(data1) { console.log('第一次请求成功, 这是返回的数据:', data1); return sendRequest('test2.html', data1); }).then(function(data2) { console.log('第二次请求成功, 这是返回的数据:', data2); return sendRequest('test3.html', data2); }).then(function(data3) { console.log('第三次请求成功, 这是返回的数据:', data3); }).catch(function(error) { //用catch捕捉前面的错误 console.log('sorry, 请求失败了, 这是失败信息:', error); });
2.Promise的基本用法
2.1 基本用法
promise对象代表一个未完成,但预计将来会完成的操作。
promise的三种状态:
1. pending : 初始值,不是fulfilled,也不是rejected
2. fulfilled : 代表操作成功
3. 代表操作失败
Promise 有两种状态改变的方式,既可以从pending 转变成fulfilled,
也可以从pending 转变成rejected.一旦状态发生改变。就不再发生变化。
之后执行 promise.then绑定的函数。
* : Promise 一旦新建就会立即执行,无法取消。这也是它的缺点之一。
var promise = new Promise ( function (resolve, reject ) { if (/* 异步操作成功 */){ resolve(data); }else{ /* 异步操作失败 */ rejected (error); } })
使用new 关键字构建 Promise。
Promise 接受一个函数作为参数,函数的两个参数分别是 resolve,rejected
这两个函数就是回调函数,由JavaScript引擎提供。
resolve 函数的作用: 再异步操作成功时调用,并将异步操作,作为参数传递出去;
rejected 函数的作用: 再异步操作失败时调用,并将异步操作,作为参数传递出去;
Promise实例生成以后,可以用then方法指定resolve状态和reject状态的回调函数。
1 var promise = new Promise(function (resolve, reject) { 2 if (/* 异步操作成功 */) { 3 resolve(data); 4 } else { 5 /* 异步操作失败 */ 6 reject(error); 7 } 8 }); 9 10 promise.then( onFulfilled, onRejected); 11 12 promise.then(function(data) { 13 //do something when success 14 }.function (error) { 15 //do something when failure 16 });
2.2 基本API
.then ()
语法:Promise.prototype.then( onFulfilled, onRejected)
对promise添加onFulfilled 和 onRejected回调
并返回一个新的Promise实例。
且返回值作为参数传入新的promise的resolve函数。
.catch ()
语法:Promise.prototype.catch( onRejected)
该方法是.then ( undefined, onRejected)的别名,用于指定发生错误时的回调函数。
1 promise.then(function(data) { 2 console.log('success'); 3 }).catch(function(error) { 4 console.log('error', error); 5 }); 6 7 /*******等同于*******/ 8 promise.then(function(data) { 9 console.log('success'); 10 }).then(undefined, function(error) { 11 console.log('error', error); 12 });
reject
方法的作用,等同于抛错。
.all ()
语法:Promise.all( iterable)
该方法用于多个promise实例,包装成一个新的promise实例
1 var p = Promise.all( [p1,p2,p3] )
Promise.all
方法接受一个数组(或具有Iterator接口)作参数,数组中的对象(p1、p2、p3)均为promise实例(如果不是一个promise,该项会被用Promise.resolve
转换为一个promise)。它的状态由这三个promise实例决定。
- 当p1, p2, p3状态都变为
fulfilled
,p的状态才会变为fulfilled
,并将三个promise返回的结果,按参数的顺序(而不是resolved
的顺序)存入数组,传给p的回调函数,如例3.8。 - 当p1, p2, p3其中之一状态变为
rejected
,p的状态也会变为rejected
,并把第一个被reject
的promise的返回值,传给p的回调函数,
.race ()
语法:Promise.race( iterable)
该方法同样是将多个Promise实例,包装成一个新的Promise实例。
1 var p = Promise.race([p1, p2, p3]);
Promise.race
方法同样接受一个数组(或具有Iterator接口)作参数。当p1, p2, p3中有一个实例的状态发生改变(变为fulfilled
或rejected
),p的状态就跟着改变。并把第一个改变状态的promise的返回值,传给p的回调函数。
.resolve()
语法:
Promise.resolve(value);
Promise.resolve(promise);
Promise.resolve(thenable);
它可以看做new Promise()
的快捷方式。
Promise.resolve('Success'); /*******等同于*******/ new Promise(function (resolve) { resolve('Success'); });
.reject()
语法:Promise.reject(reason)
这个方法和上述的Promise.resolve()
类似,它也是new Promise()
的快捷方式。
Promise.reject(new Error('error')); /*******等同于*******/ new Promise(function (resolve, reject) { reject(new Error('error')); });
关于promise
就先介绍到这边了,比较基础,有不足的地方欢迎指出,有更好的也欢迎补充~
参考资料: