本文作者:IMWeb dekuchen 原文出处:IMWeb社区 未经同意,禁止转载
国内比较流行的看法:
阮一峰: Promise 对象 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了
Promise
对象。
Promise 真正的规范,一篇长文。
截取几段: Terminology
then
method whose behavior conforms to this specification.then
method.undefined
, a thenable, or a promise).throw
statement.return
代替 resolve
不可以,无法实现链式调用,且不符合规范。
示例:
const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
if(a){
return 'this is return';
resolve('true');
console.log('this will not be exec');
throw new Error('error');
}else{
reject('false');
}
})
}
执行结果:
~/chen/FE/winSep/codes/javascript/es6promise/src ts-node return.ts
Promise { <pending> }
答案: 使用reject
而不是throw
const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
if(a){
resolve('true');
console.log('this will be exec');
throw new Error('error');
}else{
reject('false');
}
})
}
console.log(testReturn(true));
执行结果
~/chen/FE/winSep/codes/javascript/es6promise/src ts-node return.ts
this will be exec
Promise { 'true' }
解释:
Promise的构造函数,以及被 then
调用执行的函数基本上都可以认为是在 try…catch
代码块中执行的,所以在这些代码中即使使用 throw
,程序本身也不会因为异常而终止。Promise的状态也不会发生改变。
如果在Promise中使用 throw
语句的话,会被 try...catch
住,最终promise对象也变为Rejected状态。
var promise = new Promise(function(resolve, reject){
throw new Error("message");
});
promise.catch(function(error){
console.error(error);// => "message"
});
运行
Error: message
代码像这样其实运行时倒也不会有什么问题,但是如果想把 promise
设置为Rejected状态的话,使用 reject
方法则更显得合理。
所以上面的代码可以改写为下面这样。
var promise = new Promise(function(resolve, reject){
reject(new Error("message"));
});
promise.catch(function(error){
console.error(error);// => "message"
})
总结:如果在Promise中使用 throw
语句的话,会被 try...catch
住,最终promise对象也变为Rejected状态。
Error
的时候, resolve
会将Promise.then
放在微任务队列中,当所有的宏任务执行结束的时候,执行微任务队列。const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
if(a){
resolve('exec true');
console.log('this will be exec');
// throw new Error('error');
}else{
reject('false');
}
})
}
testReturn(true).then(str=>{
console.log(str);
})
执行结果
this will be exec
exec true
Error
的时候,Error
后面的代码不会被执行,但是Promise
的结果依旧是fulfilled
const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
if(a){
resolve('exec true');
console.log('this will be exec');
throw new Error('error');
console.log('this will not be exec')
}else{
reject('false');
}
})
}
testReturn(true).then(str=>{
console.log(str);
// console.log(testReturn)
}).catch(err=>{
console.log('err: ',err);
})
执行结果
this will be exec
exec true
看例子:
const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
if(a){
resolve('exec true');
console.log('this will be second exec');
}else{
reject('false');
}
})
console.log('this will first be execd');
})
}
testReturn(true).then(str=>{
console.log(str);
// console.log(testReturn)
}).catch(err=>{
console.log('err: ',err);
})
结果
this will first be execd
this will be second exec
exec true
解释:
时间 | 宏任务队列 | 微任务队列 |
---|---|---|
1 | console.log('this will first be execd') | |
2 | setTimeout | |
3 | resolve('exec true');//延迟:因为宏任务没有执行完 | |
4 | console.log('this will be second exec'); | |
最终执行顺序:
1->2->4(宏任务结束)->3(微任务结束)
一句话总结:await
等的就是一个Promise
。如果等的不是Promise
,那加了await
和不加没区别
Promise
的方法function util(args,callback){
if(err){
return callback(err);
}else{
return callback();
}
}
//调用
util(args,(err)=>{
if(err){
}else{
}
})
//Promisify
function utilPromise(args){
return new Promise((resolve,reject)=>{
if(err){
reject(err)
}else{
resolve();
}
})
}
//调用
utilPromise.then().catch()
Promise
转换为async/await
的方法async init(){
try{
await utilPromise();//resolve状态
}catch(e){
throw new Error(e); //reject状态
}
}