Promise 的主要使用
前言
回调
一直是JavaScript编程中比较令人纠结的写法,主要场景是用于处理 “并列”或者“并行”的操作,然后在回调函数中处理操作结果。这样子原生的回调写法就会带来一下的不便。
- 回调结果状态不便管理
- 回调方式自由松散,没有规范约束
例如下面的回调的写法
function func(num, callback) {
setTimeout(() => {
try {
let result = 1/num;
callback(result, null);
} catch(err) {
callback(null, err);
}
}, 10)
}
func(1, (result, err) => {
if( err ) {
console.log(err)
} else {
console.log(result)
}
})
上述代码中,发现如果要处理回调结果 result
和错误err
,后续的所有就必须在回调函数里面处理,而且回调函数里面还需要自己处理异常判断。
那如果是使用了Promise
来处理回调操作,就可以用以下写法处理。
function func(num, callback) {
return new Promise((resolve) => {
setTimeout(() => {
let result = 1/num;
resolve(result);
}, 1000)
})
}
func(1).then((result) => {
console.log(result)
}).catch((err) => {
console.log(err)
})
Promise能力
Promise 带来的能力是任务管理
,常用的方式有
new Promise(...).then(onResolved, onRejected)
- 任务状态管理
resolve
成功状态,对应Promise.resolve
reject
失败状态,对应Promise.reject
error
异常状态, 对应Promise.reject
或new Promise().catch(onRejected)
Thenabled
机制提供任务方法链new Promise().then().then().catch()
resolve
处理任务的成功状态
- 普通方式
let p = new Promise((resolve) => {
setTimeout(() => {
let result = 1;
resolve(result);
}, 1000)
})
p.then((result)=>{ console.log(result) })
- 快捷方式
let p = Promise.resolve(1)
p.then((result)=>{ console.log(result) })
reject
处理任务的失败状态
- 普通方式
let p = new Promise((resolve, reject) => {
setTimeout(() => {
let result = 2;
reject(result);
}, 100)
})
// 有两种方式获取失败状态
// 第一种,通过then 第二个函数参数处理失败状态
p.then((result)=>{
console.log('success:',result);
}, (result)=>{
console.log('fail:',result);
})
// "fail: 2"
// 第二种,或者通过,catch 获取失败状态
p.then((result)=>{
console.log('success:',result);
}).catch((result)=>{
console.log('error:',result);
})
// "error: 2"
// 注意:如果两种方式同时使用的话
// 只会被第一种方式reject操作失败的结果
p.then((result)=>{
console.log('success:',result);
}, (result)=>{
console.log('fail:',result);
}).catch((result)=>{
console.log('error:',result);
})
// "fail: 2"
- 快捷方式
let p = Promise.reject(2)
p.then(null, result => console.log('fail:', result))
// 或
p.then().catch( result => console.log('error:', result))
catch
从上述 reject
的使用过程中,会发现, catch
操作在没有设置 onRejected 处理的时候,会被catch
捕获失败处理。同时catch
也会捕获 onResolved 和 onRejected中出现的错误。
- 正常情况下直接捕获
reject
结果
let p = new Promise((resolve, reject) => {
reject(3)
});
p.then((result) => {
console.log('success:', result)
}).catch((result) => {
console.log('error:', result)
})
// "error: 3"
- 捕获 onResolved 中错误异常
let p = new Promise((resolve) => {
resolve(3)
});
p.then((result) => {
throw new Error('custom resolve error!')
console.log('success:', result)
}).catch((err) => {
console.log('Custom error:', err)
})
// "Custom error: Error: custom resolve error!"
- 捕获 onRejected 中错误异常
let p = new Promise((resolve) => {
reject(3)
});
p.then(null, (result) => {
throw new Error('custom reject error!')
console.log('fail:', result)
}).catch((err) => {
console.log('Custom error:', err)
})
// "Custom error: Error: custom reject error!"
后记
由于本书主要介绍 Koa.js
的原理,主要涉及到Promise
的resolve
、reject
和catch
更多 关于 Promise
的原理和使用,请查看一下文档:
https://docs.microsoft.com/zh-cn/scripting/javascript/reference/promise-object-javascript