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

results matching ""

    No results matching ""