Promise是什么
MDN解释:
- The Promise object is used for asynchronous computations.
- A Promise represents a value which may be available now,or in the future,or never.
按照用途来解释:
- 主要用于异步计算。
- 可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果。
- 可以在对象之间传递和操作Promise,帮助我们处理队列。
异步操作可以避免界面冻结
异步操作的常见语法:
1. 事件侦听与响应:
document.getElementById('start').addEventListener('click',start,false);
function start(){
//响应事件,进行相应的操作
}
//jQuery用‘.on()’也是事件侦听
$('#start').on('click',start);
2. 回调
//比较常见的有Ajax
$.ajax('http://baidu.com',{
success:function(res){
//这里是回调函数
}
});
//或者在页面加载完毕后回调
$(function(){
//这里也是回调函数
});
有了node.js之后,对异步的依赖进一步加剧了。无阻塞高并发是node.js的招牌,要达到无阻塞高并发异步操作是其保障。
//稍有不慎就会陷入“回调地狱”。
a(function(resultsFromA){
b(resultsFromA,function(resultsFromB){
c(resultsFromB,function(resultsFromC){
d(resultFromC,function(resultsFromD){
e(resultsFromD,function(resultFromE){
})
})
})
});
});
使用promise的时候我们先要初始化一个Promise实例,在这个实例中我们要传入一个参数,这个参数是一个函数,我们称它为执行器(executor),这个执行器函数接收两个参数,一个是resolve,一个是reject。我们可以把之前异步执行的耗时很长的放在执行器里面去执行,当执行完成之后,如果判定执行成功就调用resolve()方法;如果执行出错了就调用reject()方法。这两个函数调用之后就会改变当前Promise的状态,promise的状态改变之后就会调用then()函数里面对应的处理函数,如果调用的是resolve()也就是当前的promise执行成功了就会调用then()里面的第一个函数参数;如果调用的是reject()也就是当前promise执行失败了或者是抛出一个错误,那么当前promise的状态就是出错的状态就会执行then()函数里的第二个参数函数。
new Promise(
function(resolve,reject){//执行器函数(executor)
//这里有一段耗时很长的异步操作
resolve();//数据处理成功
reject();//数据处理失败
}
)
.then(function(){
//成功
},function(){
//失败
});
-
Promise是一个代理对象,它和原先要进行的操作并无关系。我们只是把原先的操作放在了执行器里面。
-
它通过引入一个回调避免引入更多的回调
-
Promise有3个状态:
- pending初始状态:我们实例化的时候;
- fulfilled操作成功:当执行完毕我们调用resolve的时候它就会被切换到fulfilled实现了的状态;
- rejected操作失败:当我们调用reject的时候它就会被置为否决的状态;
-
Promise状态发生改变之后它就会触发.then()里的响应函数来处理后续步骤。
-
Promise的状态一经改变就不会再变。
每一个.then()
都会返回一个新的Promise实例
最简单的实例:
console.log('here we go');
new Promise(resolve => {
setTimeout(() => {
resolve('hello');
},2000);
})
.then(value => {
console.log(value + 'world')
})
两步执行的范例:
console.log('here we go');
new Promise(resolve => {
setTimeout(() => {
resolve('hello');
}, 2000);
})
.then(value => {
console.log(value);
//这里返回了一个新的Promise实例
return new Promise(resolve => {
setTimeout(() => {
resolve('world');
}, 2000);
})
})
.then(value => {
console.log(value + ' world');
});
对已完成的Promise执行then:
console.log('start');
let promise = new Promise(resolve => {
setTimeout(() => {
console.log('the promise fullfilled');
resolve('hello world');
}, 1000);
});
setTimeout(() => {
promise.then(value => {
console.log(value);
});
}, 3000);
//先输出'start'开始,1秒钟之后输出'the promise fullfilled',3秒减去1秒,就是再过2秒钟之后再输出'hello world',说明Promise是有队列的特性的。
then()里不返回Promise:
console.log('here we go');
new Promise(resolve => {
setTimeout(() => {
resolve('hello');
}, 2000);
})
.then(value => {
console.log(value);
console.log('everyone');
(function(){
return new Promise(resolve => {
setTimeout( () =>{
console.log('Mr.Laurence');
resolve('Merry Vehx');
},2000);
})
})();//立刻执行函数的匿名函数
return false
})
.then(value =>{
console.log(value + ' world');
});
- 在Promise里面如果你不直接返回一个Promise实例,它就会默认的去执行下一个环节,即使里面返回的是false也不会影响到下一步,false会直接传到下一个环节,即使把false注释掉没有明确返回值时返回的会是undefined
- 第二个then()里面没有直接返回Promise实例而是在立刻执行函数的匿名函数里返回的
.then()
- .then()接受两个函数作为参数,分别代表fulfilled状态下的响应函数和rejected状态下的响应函数
- .then()返回一个新的Promise实例,所以它可以链式调用
- 当前面的Promise状态改变时,.then()根据其最终状态来选择特定状态响应函数来执行
- 状态响应函数可以返回新的Promise,或者其它值。如果返回的时新的Promise实例,那么下一级.then()会在新的Promise状态改变之后执行,如果返回的是其它值则会立刻执行下一级的.then()