Promise 对象用于异步计算.
一个Promise表示一个现在、将来或永不可能可用的值.
按照用途来解释
1.主要用于异步计算
2.可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3.可以在对象之间传递和操作Promise,帮助我们处理队列.
回调有四个问题
1.嵌套层次很深,难以维护
2.无法正常使用return 和throw
3.无法正常检索堆栈信息
4.多个回调之间难以建立联系
new Promise(
/* 执行器 executor */
function (resolve, reject) {
// 一段耗时很长的异步操作
resolve(); //数据处理完成
reject(); //数据处理出错
}
)
.then(function A() {
//成功,下一步
}, function B() {
//失败,做相应处理
});
Promise详解
1.Promise是一个代理对象,它和原先要进行的操作并无关系.
2.它通过引入一个回调,避免更多的回调.
Promise有3个状态
1. pending[待定] 初始状态
2.fulfilled[实现] 操作成功
3.rejected[被否决] 操作失败
Promise 状态发生改变,就会触发.then()里的响应函数处理后续步骤.
Promise 状态一经改变,不会再变.
Promise 实例一经创建,执行器立即执行.
简单demo-1
console.log('here we go');
new Promise(resolve => {
setTimeout(() => {
resolve('hello');
},2000);
})
.then(value => {
console.log(value +' world');
});
简单demo-2
console.log('here we go');
new Promise(resolve => {
setTimeout(() => {
resolve('hello');
},2000);
})
.then( value => {
console.log(value);
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 fulfilled');
resolve('hello, world');
},1000);
});
setTimeout(() => {
promise.then( value => {
console.log(value)
});
},3000);
.then
1. .then()接受两个函数作为参数,分别代表fulfilled 和 rejected
2. .then()返回一个新的Promise实例,所以它可以链式调用
3. 当前面的Promise状态改变时, .then()根据其最终状态,选 择特定的状态响应函数执行
4. 状态响应函数可以返回新的Promise,或其它值
5. 如果返回新的Promise, 那么下一级 .then()会在新Promise状 态改变之后执行
6. 如果返回其它任何值,则会立刻执行下一级 .then()
.then()里有 .then() 的情况
1. 因为.then() 返回的还是Promise实例
2. 会等里面的 .then()执行完,在执行外面的
3.对于我们来说,此时最好将其展开,会更好读
简单demo_3(没展开)
console.log('start');
new Promise( resolve => {
console.log('Step 1');
setTimeout(() => {
resolve(100);
},1000);
})
.then( value => {
return new Promise(resolve => {
console.log('Step 1-1');
setTimeout(() => {
resolve(110);
},1000);
})
.then( value => {
console.log('Step 1-2');
return value;
})
.then( value => {
console.log('Step 1-3');
return value;
});
})
.then(value => {
console.log(value);
console.log('Step 2');
})
结果
start
Step 1
Step 1-1
Step 1-2
Step 1-3
110
Step 2
简单demo_3(展开后)
console.log('start');
new Promise( resolve => {
console.log('Step 1');
setTimeout(() => {
resolve(100);
},1000);
})
.then( value => {
return new Promise(resolve => {
console.log('Step 1-1');
setTimeout(() => {
resolve(110);
},1000);
})
})
.then( value => {
console.log('Step 1-2');
return value;
})
.then( value => {
console.log('Step 1-3');
return value;
})
.then(value => {
console.log(value);
console.log('Step 2');
})
结果一样
错误处理
Promise 会自动捕获内部异常,并交给rejected响应函数处理
错误处理的两种做法:
1.reject('错误信息').then(null, message => {})
2.throw new Error('错误信息').catch( message => {})
推荐使用第二种,更加清晰好读,并且可以捕获前面的错误
注意:
强烈建议在所有队列最后都加上.catch(),以避免漏洞错误处理造成意想不到的问题
Promise.all()
批量执行
1.Promise.all([p1, p2, p3, ...])用于将多个Promise实例,包装成一个新的Promise实例
2.返回的实例就是普通 Promise
3.它接受一个数组作为参数
4.数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变。
5.当所有子Promise都完成,该Promise完成,返回值是全部值的数组
6.有任何一个失败,该Promise失败,返回值是第一个失败的子Promise的结果。
简单demo
console.log('hero we go');
Promise.all([1,2,3])
.then( all => {
console.log('1', all);
return Promise.all([function () {
console.log('ooxx');
},'xxoo',false]);
})
.then( all => {
console.log('2: ', all);
let p1 =new Promise( resolve => {
setTimeout(() => {
resolve('I\'m P1');
},1500);
});
let p2 =new Promise( resolve => {
setTimeout(() => {
resolve('I\'m P2');
},1450);
});
return Promise.all([p1,p2]);
})
.then( all => {
console.log('3: ', all);
let p1 =new Promise( resolve => {
setTimeout(() => {
resolve('I\'m P1');
},1500);
});
let p2 =new Promise( (resolve, reject) => {
setTimeout(() => {
reject('I\'m P2');
},1000);
});
let p3 =new Promise( (resolve, reject) => {
setTimeout(() => {
reject('I\'m P3');
},3000);
});
return Promise.all([p1,p2,p3]);
})
.then( all => {
console.log('all', all);
})
.catch( err => {
console.log('Catch: ', err);
});
结果:
hero we go
1 [ 1, 2, 3 ]
2: [ [Function], 'xxoo', false ]
3: [ 'I\'m P1', 'I\'m P2' ]
Catch: I'm P2
Promise.all()最常见就是和.map()连用
Promise.resolve()
返回一个fulfilled的Promise实例,或原始Promise实例
1.参数为空,返回一个状态为fulfilled的Promise实例
2.参数是一个跟Promise无关的值,同上,不过fulfuilled响应函数会得到这个参数
3.参数为Promise实例,则返回该实例,不做任何修改
4.参数为thenable,立刻执行它的.then()