第十一章:Promise 与异步函数

本文深入探讨了JavaScript中的Promise和异步函数。从异步编程的基础,如同步与异步的区别,到Promise的A+规范,详细阐述了Promise的状态机、实例方法以及连锁和合成。同时,还介绍了异步函数的特性,包括执行策略和错误处理。
摘要由CSDN通过智能技术生成

第十一章:Promise 与异步函数

11.1 异步编程

11.1.1 同步与异步


11.1.2 以往的异步编程模式

  • 回调地狱
1. 异步返回值
function double(value, callback) {
    setTimeout(() => callback(value * 2), 1000);
}

double(3, (x) => console.log(x));   // 6    大约 1000ms 后
2. 失败处理
function double(value, success, failure) {
    setTimeout(() => {
        try {
            if (typeof value !== 'number') {
                throw ('error');
            }
            success(value * 2);
        }
        catch (e) {
            failure(e);
        }
    }, 1000);
}
3. 嵌套异步回调
const successCallback = (x) => {
    double(x, (y) => console.log(y));
};

11.2 Promise

11.2.1 Promise/A+ 规范


11.2.2 Promise 基础

let p = new Promise(() => { });
1. Promise 状态机
  • 状态
    • 待定 pending
    • 解决 resolved
    • 拒绝 rejected
2. 解决值、拒绝理由及 Promise 用例

3. 通过执行函数控制 Promise 状态
  • resolve()
  • reject()
4. Promise.resolve()
  • 幂等
5. Promise.reject()
  • 非幂等
6. 同步/异步执行的二元性

11.2.3 Promise 的实例方法

1. 实现 Thenable 接口
  • then()实现了 Thenable 接口
2. Promise.prototype.then()
  • 参数:onResolvedonRejected
3. Promise.prototype.catch()
  • 参数:onRejected
  • 相当于 Promise.prototype.then(null, onRejected)
4. Promise.prototype.finally()
  • onResolvedonRejected后都会执行
  • 不能知道 Promise 的状态
5. 非重入 Promise 方法
const promise = new Promise((resolve, reject) => {
    // 声明时就开始执行
    console.log(1);
    resolve(5);
    console.log(2);
}).then(value => console.log(value));

// 微任务
promise.then(() => {
    console.log(3);
});

console.log(4);

// 宏任务
setTimeout(function () {
    console.log(6);
});

                            // output: 1 2 4 5 3 6
6. 临近处理程序的执行顺序

7. 传递解决值和拒绝理由

8. 拒绝 Promise 与拒绝错误处理

11.2.4 Promise 连锁与 Promise 合成

1. Promise 连锁
const p = new Promise((resolve, reject) => {
    console.log(1);
    setTimeout(resolve, 1000);
});

p.then(() => new Promise((resolve, reject) => {
    console.log(2);
    setTimeout(resolve, 1000);
}))
    .then(() => new Promise((resolve, reject) => {
        console.log(3);
        setTimeout(resolve, 1000);
    }))
    .then(() => new Promise((resolve, reject) => {
        console.log(4);
        setTimeout(resolve, 1000);
    }));
// 1 2 3 4
2. Promise 图

3. Promise.all()Promise.race()
  • Promise.all()
    • 包含的 Promise 全部解决才解决,有一个待定/拒绝则也会是相应的状态
    • 全部解决的情况,解决值是一个数组
    • 拒绝的情况,拒绝理由是第一个拒绝的 Promise 的理由,其他的静默处理
let p1 = Promise.all([
    Promise.resolve(),
    Promise.resolve()
]);

// 可迭代对象的元素会通过 Promise.resolve() 进行转换
let p2 = Promise.all([2,3]);

// 等价于 Promise.resolve()
let p3 = Promise.all([]);

// 报错
// let p4 = Promise.all();
  • Promise.race()
    • 返回一个包装 Promise,是最先解决或拒绝的 Promise 的镜像
// 等同于 new Promise(()=>{})
let p3 = Promise.race([]);
let p = Promise.race([
    Promise.resolve(3),
    Promise.resolve(5),
    new Promise((resolve, reject) => setTimeout(reject, 1000))
]);

setTimeout(console.log, 0, p);  // Promise {3}
4. 串行 Promise 合成
function add2(x) { return x + 2; }
function add3(x) { return x + 3; }
function add5(x) { return x + 5; }

function compose(...fns) {
    return (x) => fns.reduce(/* arg1 */(promise, fn) => promise.then(fn), 
                             /* arg2 */Promise.resolve(x));
}

let add10 = compose(add2, add3, add5);
add10(8).then(console.log);     // 18

11.2.5 Promise 扩展

1. Promise 取消
2. Promise 进度通知
  • p345(第四版)

11.3 异步函数

  • async / await(ES8)

11.3.1 异步函数

1. async
  • Promise.reject()不会被 catch()捕获
2. await
  • 使用了 awaitreject()会释放错误值,后面的代码不会执行
3. await的限制

11.3.2 停止和恢复执行

async function foo() {
    console.log(await Promise.resolve('foo'));
}

async function bar() {
    console.log(await 'bar');
}

async function baz() {
    console.log('baz');
}

foo()
console.log(1);
bar();
console.log(2);
baz();
console.log(3);         // 1  2  baz  3  foo  bar

11.3.3 异步函数策略

1. 实现 sleep()
async function sleep(delay) {
    return new Promise((resolve) => setTimeout(resolve, delay));
}
2. 利用平行执行

3. 串行执行 Promise

4. 栈追踪与内存管理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值