[JavaScript]_认识Promise(二)

124 阅读3分钟

这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。

认识Promise(一) 有提到过,使用Promise.reject()抛出的错误不能通过 try/catch 捕获,而只能通过拒绝处理程序捕获。

try {
    throw new Error('foo');
} catch(e) {
    console.log(e); // Error: foo
}

try {
    Promise.reject(new Error('bar'));
} catch(e) {
    console.log(e);
}

image.png

从上面例子中可以明显看出Promise的特性,Promise在同步执行模式中使用,是一个同步对象,但也是异步执行模式的媒介。Promise的解决值(解决或拒绝)是通过浏览器异步消息队列处理的,并不是抛出到同步代码中执行,只能通过实例方法如thencatch捕获到信息。

实例方法

期约实例的方法是连接外部同步代码与内部异步代码之间的桥梁。

为什么说他是连接外部同步代码与内部异步代码的桥梁呢?
因为Promise对象本身是同步的,但其内部执行是异步的,这个异步处理结果只能通过Promise实例方法捕获到。

then()

  • 方法接收参数 then 方法可以接收两个参数:一个是处理 兑现 的处理程序(以下代码中onResovled指兑现的处理函数参数),一个是处理 拒绝 的处理程序(以下代码中onRejected指拒绝的处理函数参数);这两个参数都是可选的,不是必须的。
let p1 = new Promise((resolve, reject)=> {
    setTimeout(resolve, 2000);
})
let p2 = new Promise((resolve, reject)=> {
    setTimeout(reject, 2000);
})

p1.then(
    (res)=> console.log('p1',res),
    (err)=> console.log('p1',err));
p2.then(
    (res)=> console.log('p2',res),
    (err)=> console.log('p2',err));
    
// 2s后
// p1 undefined
// p2 undefined
  1. 如果传给 then 方法的不是函数呢?
let p1 = new Promise((resolve, reject)=> {
    setTimeout(resolve, 2000);
})
p1.then(1);//非函数类型的参数都会被静默忽略, 毫无意义。
  1. 如果只需要onRejected的处理程序呢?
let p1 = new Promise((resolve, reject)=> {
    setTimeout(reject, 2000);
})
p1.then(null, (err) => {console.log('p1', err)});// 需要在onResovled处理程序的位置用null站位即可。
  • 方法返回值 then 方法会返回一个新的Promise实例对象。这个返回的新的Promises实例 构建规则具体如下:
let rs = Promise.resolve('哈哈');
let rj = Promise.reject('我错了');
  1. 不传处理程序时,使用Promise.resolve()包装上一个Promise解决之后的值。向后传
let p1 = rs.then(); // Promise {<fulfilled>: '哈哈'}
let p11 = rj.then(); // Promise {<rejected>: '我错了'}
  1. 有处理程序,没有显示的返回语句, Promise.resolve()会包装默认的返回值 undefined。onRejected处理程序的返回值也会被Promise.resolve()包装
let p2 = rs.then(()=>{}); // Promise {<fulfilled>: undefined}
let p22 = rj.then(null, ()=> {}); // Promise {<fulfilled>: undefined}
  1. 有处理程序,有显示的返回语句,onResovled处理程序与onRejected处理程序的返回值都是一样的。因为onRejected处理程序的返回值也会被Promise.resolve()包装。
let p30 = rs.then(() => 123); // Promise {<fulfilled>: 123}
let p31 = rs.then(() => Promise.resolve(123)); // Promise {<fulfilled>: 123}
let p32 = rs.then(() => Promise.reject()); // Promise {<rejected>: undefined}

let p330 = rj.then(null, () => 123); // Promise {<fulfilled>: 123}
let p331 = rj.then(null, () => Promise.resolve(123)); // Promise {<fulfilled>: 123}
let p332 = rj.then(null, () => Promise.reject()); // Promise {<rejected>: undefined}

  1. 有处理程序,抛出错误; 抛出异常会返回拒绝的Promise对象,但如果是返回错误的话,还是使用Promise.resolve()包装返回错误结果。
// 
let p4 = rs.then(() => {throw '我错了啊';}); // Promise {<rejected>: '我错了啊'}
let p44 = rj.then(null, () => {throw '我错了啊';}); // Promise {<rejected>: '我错了啊'}

let p5 = rs.then(() => Error('返回一个错误'));// Promise {<fulfilled>: Error: 返回一个错误55}
let p55 = rj.then(null, () => Error('返回一个错误55')); // Promise {<fulfilled>: Error: 返回一个错误55}