@[TOC](JS 的 Promise详解)欧诺个鱼
1、概念
ES 6 开始支持 Promise。
Promise 对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简而言之,就是处理异步请求的。
之所以叫做 Promise,就是承诺做这件事,如果成功则怎么处理,失败则怎么处理。
// 语法
new Promise(
// 下面定义的函数是 executor
function(resolve, reject) {
...
}
)
2、executor
- executor 是一个带有 resolve 和 reject 两个参数的函数
- executor 函数在 Promise 构造函数执行时立即执行,被传递 resolve 和 reject 函数(executor 函数在 Promise 构造函数返回新建对象前被调用)
- executor 内部通常会执行一些异步操作,一旦完成,可以调用 resolve 函数来将 Promise 状态改成 fulfilled (即完成),或者在发生错误时将它的状态改为 rejected (即失败)
- 如果在 executor 函数中抛出一个错误,那么该 Promise 状态为 rejected 。executor 函数的返回值被忽略
- executor 中,reslove 或 reject 只能执行其中一个函数
3、Promise 的状态
- pending: 初始状态,不是成功或失败状态
- fulfilled: 意味着操作成功完成
- rejected: 意味着操作失败
3.1 setInterval 介绍
# 间隔多少毫秒就执行函数一次,循环执行
# function 延时到的时候执行的函数
# delay 延时,缺省0,立即执行
setInterval(function[,delay]);
setInterval(() => {
console.log('I am working!')
}, 1000)
Info: Start process (上午10:26:11)
I am working!
I am working!
I am working!
Process canceled // F9
Info: End process (上午10:26:19)
3.2 setTimeout 介绍
# 等待多少毫秒就执行函数一次,结束
# function 延时到的时候执行的函数
# delay 延时,缺省0,立即执行
setTimeout(function[,delay]);
setTimeout(() => {
console.log('I am working!')
}, 2000)
Info: Start process (上午10:38:25)
I am working!
Info: End process (上午10:38:28)
3.3 Promise 状态示例
var myPromise = new Promise(function(resolve, reject){
console.log(1, 'Do sth.')
setTimeout(() => {
console.log(2, '========');
resolve('Ok.');
}, 3000);
})
console.log(3, myPromise)
setInterval(() => {
console.log(4, myPromise, '++++++++')
}, 1000)
Info: Start process (上午10:48:49)
1 'Do sth.'
3 Promise { <pending> }
4 Promise { <pending> } '++++++++'
4 Promise { <pending> } '++++++++'
2 '========'
4 Promise { 'Ok.' } '++++++++'
4 Promise { 'Ok.' } '++++++++'
Process canceled
Info: End process (上午10:48:59)
4、Promise.then(onFulfilled, onRejected)
- 参数是 2 个函数,根据当前 Promise 对象 A 的状态来调用不同的函数,fulfilled 走 onFulfilled 函数 F1, rejected 走 onRejected 函数 F2
- then 的返回值是一个 新的Promise对象B,执行任意一个回调函数,对这个 Promise 对象来说就是其返回值。调用任何一个函数后,其返回值可以被后续的 then 方法继续捕捉(链式)
- 任何一个回调函数执行,其返回值 ret 被 resolve(ret),作为 B 的完成结果
var myPromise = new Promise(function(resolve, reject){
console.log(1, 'Do sth.')
setTimeout(() => {
console.log(2, '========');
resolve('Ok.');
}, 3000);
})
console.log(3, myPromise)
setInterval(() => {
console.log(4, myPromise, '++++++++')
}, 1000)
let pro1 = myPromise.then(
value => {
console.log(5, 'Successful.');
return 11111;
},
reason => {
console.log(6, 'Failed.')
return 22222;
}
)
setInterval(() => {
console.log(7, pro1, '@@@@@')
}, 1000)
Info: Start process (上午11:02:43)
1 'Do sth.'
3 Promise { <pending> }
4 Promise { <pending> } '++++++++'
7 Promise { <pending> } '@@@@@'
4 Promise { <pending> } '++++++++'
7 Promise { <pending> } '@@@@@'
2 '========'
5 'Successful.'
4 Promise { 'Ok.' } '++++++++'
7 Promise { 11111 } '@@@@@'
4 Promise { 'Ok.' } '++++++++'
7 Promise { 11111 } '@@@@@'
Process canceled
Info: End process (上午11:02:53)
5、Promise.catch
- 为当前 Promise 对象 A 添加一个拒绝回调 F,返回一个 新的Promise对象B
- 如果 A 进行 fulfilled 状态,则 A 的完成结果作为 B 的完成结果
- 如果 A 进入 rejected 状态,回调 F 执行, F 的返回值 ret 来 resolve(ret)
5.1 示例 1
var myPromise = new Promise(function(resolve, reject){
console.log(1, 'Do sth.')
setTimeout(() => {
console.log(2, '========');
resolve('Ok.');
}, 3000);
})
console.log(3, myPromise)
setInterval(() => {
console.log(4, myPromise, '++++++++')
}, 1000)
let pro1 = myPromise.catch(
reason => {
console.log(5, reason, '&&&&&&&&')
return 22222;
}
)
setInterval(() => {
console.log(6, pro1, '@@@@@')
}, 1000)
Info: Start process (上午11:07:53)
1 'Do sth.'
3 Promise { <pending> }
4 Promise { <pending> } '++++++++'
7 Promise { <pending> } '@@@@@'
4 Promise { <pending> } '++++++++'
7 Promise { <pending> } '@@@@@'
2 '========'
4 Promise { 'Ok.' } '++++++++'
7 Promise { 'Ok.' } '@@@@@'
4 Promise { 'Ok.' } '++++++++'
7 Promise { 'Ok.' } '@@@@@'
4 Promise { 'Ok.' } '++++++++'
7 Promise { 'Ok.' } '@@@@@'
4 Promise { 'Ok.' } '++++++++'
7 Promise { 'Ok.' } '@@@@@'
4 Promise { 'Ok.' } '++++++++'
7 Promise { 'Ok.' } '@@@@@'
Process canceled
Info: End process (上午11:08:00)
5.2 示例 2
var myPromise = new Promise(function(resolve, reject){
console.log(1, 'Do sth.')
setTimeout(() => {
console.log(2, '========');
reject('Not Ok.');
}, 3000);
})
console.log(3, myPromise)
setInterval(() => {
console.log(4, myPromise, '++++++++')
}, 1000)
let pro1 = myPromise.catch(
reason => {
console.log(5, reason, '&&&&&&&&')
return 22222;
}
)
setInterval(() => {
console.log(6, pro1, '@@@@@')
}, 1000)
Info: Start process (上午11:12:49)
1 'Do sth.'
3 Promise { <pending> }
4 Promise { <pending> } '++++++++'
6 Promise { <pending> } '@@@@@'
4 Promise { <pending> } '++++++++'
6 Promise { <pending> } '@@@@@'
2 '========'
5 'Not Ok.' '&&&&&&&&'
4 Promise { <rejected> 'Not Ok.' } '++++++++'
6 Promise { 22222 } '@@@@@'
4 Promise { <rejected> 'Not Ok.' } '++++++++'
6 Promise { 22222 } '@@@@@'
4 Promise { <rejected> 'Not Ok.' } '++++++++'
6 Promise { 22222 } '@@@@@'
4 Promise { <rejected> 'Not Ok.' } '++++++++'
6 Promise { 22222 } '@@@@@'
4 Promise { <rejected> 'Not Ok.' } '++++++++'
6 Promise { 22222 } '@@@@@'
Process canceled
Info: End process (上午11:12:57)
6、Promise 的 两个方法
- Promise.resolve(value) 返回 状态为 fulfilled 的 Promise 对象
- Promise.reject(reason) 返回 状态为 rejected 的 Promise 对象
6.1 示例 1
function runAsync() {
return new Promise (function(resolve, reject){
setTimeout(function(){
console.log('Do Sth...');
resolve('OK...')
// reject('NOT OK...');
}, 3000);
});
}
runAsync().then(
value => {
console.log(1, value);
return Promise.reject(value + '*===*');
},
reason => {
console.log(2, reason);
return Promise.resolve(reason + '===');
}
).catch(
reason => {
console.log(3, reason);
return Promise.resolve(reason + '*===*');
}
).then(
reason => {
console.log(4,reason);
console.log(5, 'Reason + Promise END')
return Promise.resolve(reason + "===");
},
value => {
console.log(6, value);
console.log(7, 'Value + Promise END');
}
)
console.log(8, "===== FIN =====")
Info: Start process (上午12:25:25)
8 '===== FIN ====='
Do Sth...
1 'OK...'
3 'OK...*===*'
4 'OK...*===**===*'
5 'Reason + Promise END'
Info: End process (上午12:25:28)
6.2 示例 2
function runAsync() {
return new Promise (function(resolve, reject){
setTimeout(function(){
console.log('Do Sth...');
// resolve('OK...')
reject('NOT OK...');
}, 3000);
});
}
runAsync().then(
value => {
console.log(1, value);
return Promise.reject(value + '*===*');
},
reason => {
console.log(2, reason);
return Promise.resolve(reason + '===');
}
).catch(
reason => {
console.log(3, reason);
return Promise.resolve(reason + '*===*');
}
).then(
reason => {
console.log(4,reason);
console.log(5, 'Reason + Promise END')
return Promise.resolve(reason + "===");
},
value => {
console.log(6, value);
console.log(7, 'Value + Promise END');
}
)
console.log(8, "===== FIN =====")
Info: Start process (上午12:25:56)
8 '===== FIN ====='
Do Sth...
2 'NOT OK...'
4 'NOT OK...==='
5 'Reason + Promise END'
Info: End process (上午12:25:59)