异步编程promise

异步编程发展

异步编程经历了 callback、promise、async/await、generator四个阶段,其中promise和async/await使用最为频繁,而generator因为语法晦涩难懂,很少使用。

本文主要讲述promise如何使用。


promise语法

promise的三种状态

pending状态:

未调用resolve或者reject时候处于pending状态

fullfilled状态:

调用resolve后处于fullfilled状态

rejected状态:

调用reject后处于rejected状态。如果在pending状态时候,执行任务抛出错误,则变成reject状态。


promise对象的方法then、catch、all、race、allSettled

then

then方法不传参数

// 第一个promise
const p = new Promise(resolve => {
    throw new Error('test'); // 抛出错误
});

// 第二个promise
p.then(
    () => {} // 这里是状态变为fullfilled的回调函数
    // 这里空着的,本应该填的是状态变为rejected的回调函数,所以不传递参数
)
// 第三个promise
.then(
    data => console.log('resolve', data),
    err => console.log('reject', err)
)
// 运行结果:reject Error: test
// 可见,第一个promise抛出的错误,即使第二个promise没有rejected回调函数,第三个promise的rejected回调函数依旧能接受到参数
// 结论:无论onFullfilled还是onRjected中,上一个promise不对参数进行处理,下一个promise进行处理

then方法回调不返回值

// 第一个promise
const p = new Promise(resolve => {
    resolve('test')
});

// 第二个promise
p.then(() => {
    () => {} // 状态变成fullfilled的回调函数,没有返回值
})
// 第三个promise
.then(
    data => console.log('resolve', data),
    err => console.log('reject', err)
)
// 运行结果:resolve undefined
// 第一个promise
const p = new Promise(() => {
    throw new Error('error');
});

// 第二个promise
p.then(
    () => {}, 
    () => {} // 状态变成rejected的回调函数,没有返回值
)
// 第三个promise
.then(
    data => console.log('resolve', data),
    err => console.log('reject', err)
)
// 运行结果:resolve undefined
// 结论:无论onFullfilled还是onRjected中,then方法回调不返回值,状态都会变成fullfilled,走fullfilled的回调函数

then方法回调返回普通值

var p = new Promise(resolve => {
    throw new Error('test');
});

p.then(
    () => { return 'a' },
    () => { return {b: 1} }
).then(
    (data) => console.log("resolve", data),
    (err) => console.log("reject", err)
);
// 运行结果:resolve {b: 1}
// 结论:无论onFullfilled还是onRjected中,then方法回调返回普通值,状态都会变成fullfilled,走fullfilled的回调函数

then方法回调返回promise

var p = new Promise(resolve => {
    throw new Error('test');
});

p.then(
    () => { return 'a' },
    () => { return Promise.resolve('test') }
).then(
    (data) => console.log("resolve", data),
    (err) => console.log("reject", err)
);
// 运行结果:resolve test
// 结论:无论onFullfilled还是onRjected中,返回一个promise对象,则以该promise的任务和状态返回新的promise

then方法回调返回thenable对象

var p = new Promise((r) => {throw new Error('test')});


p.then(
    () => ({then: function(resolvePromise, rejectPromise) {resolvePromise('resolvePromise')}}),
    e => ({then: function(resolvePromise, rejectPromise) {rejectPromise('rejectPromise')}})
)
.then(
    data => console.log('resolve', data),
    e => console.log('reject', e)
);

// 运行结果:reject rejectPromise
// 结论:无论onFullfilled中还是onRejected中,返回一个thenable对象,则调用该对象的then方法,该then方法接收两个参数resolvePromise和rejectPromise。
// 如果then中调用了resolvePromise,则返回的promise状态置为fullfilled,如果then中调用了rejectPromise,或者then中抛出异常,则返回的Promise状态置为rejected。
// 在调用resolvePromise或者rejectPromise之前,返回的promise处于pending状态。

then方法回调抛出错误

无论onFullfilled中还是onRejected中,抛出错误,则以rejected为状态返回新promise。


catch

catch方法和then方法的reject回调用法相同,如果这时候任务处于rejected状态,则直接执行catch,catch的参数就是reject的reason;

var p = new Promise(resolve => {
    throw new Error('test');
});

// catch写法
p.catch((err) => {
    console.log(err);
})
// 两种写法等价
p.then(
    undefined,
    (err) => {
        console.log(err);
    }
)

all

Promise.all方法接收一个promise数组作为参数,返回一个promise,当参数的数组中的所有promise都resolve时候,返回的promise才会resolve;而若有一个参数的数组中的promise reject,返回的promise就会reject。

var p1 = Promise.resolve(1);

var p2 = new Promise(resolve => {
    setTimeout(() => {
        resolve(2);
    }, 1000);
})

Promise.all([p1, p2])
.then(
    ([result1, result2]) => {console.log('resolve', result1, result2);}
)
// 运行结果:resolve 1 2

race

Promise.race接收一个promise数组作为参数,返回一个新的promise。当参数数组中其中一个promise resolve或者reject,返回的promise就相应地改变状态。

var p1 = Promise.reject(1);
var p2 = new Promise(resolve => {
    setTimeout(() => {
      resolve(2);
  }, 1000);
});

Promise.race([p1, p2])
.then(
        data => {console.log('resolve', data);},
    e => {console.log('reject', e);}
);

// 运行结果:reject 1

allSettled

Promise.allSettled用于多个异步任务都结束(完成或者失败)时候,再执行后续任务的场景。

Promise.allSettled接收一个promise数组作为参数,返回一个promise。当参数数组中所有promise状态改变后,返回的promise变为fullfilled状态。

返回的promise的onFullfilled参数接收一个结果数组作为参数,数组对应Promise.allSettled传入的promise数组。结果数组每个元素是一个对象,格式固定:{status, value, reason},标识状态、resolve返回值、reject原因。

var p1 = Promise.reject(1);
var p2 = new Promise(resolve => {
    setTimeout(() => {
      resolve(2);
  }, 1000);
});

Promise.allSettled([p1, p2])
.then(
    data => {console.log('resolve', data);},
);

// 运行结果:resolve [{status: "rejected", reason: 1}, {status: "fulfilled", value: 2}]
posted @ 2022-08-31 10:09  笔下洛璃  阅读(87)  评论(0编辑  收藏  举报