func-package

函数库, 面向复杂业务场景的 js 类库

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.rejectnew 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的原理,主要涉及到Promiseresolverejectcatch 更多 关于 Promise 的原理和使用,请查看一下文档:

https://docs.microsoft.com/zh-cn/scripting/javascript/reference/promise-object-javascript