2021-8-12这篇关于Promise用法的标题我不知道怎么起了

Promise

1.Promise 是什么,结构?

1.1本质

Promise(MDN)本质上是一个函数返回的对象,在上面绑定回调后就不需要在一开始把回调函数作为参数传入。–>异步函数调用;一旦Promise的值确定后就不再改变。
从语法上来说:Promise是一个构造函数
从功能上来说:Promise对象用来封装一个异步操作并可以获得其结果

  • 对比:then 是原型对象方法;new Promise 是实例对象方法;Promise.all是 promise函数对象方法

  • 例子:假设现在有一个名为 createAudioFileAsync() 的函数,它接收一些配置和两个回调函数,然后异步地生成音频文件。一个回调函数在文件成功创建时被调用,另一个则在出现异常时被调用。
    之前的用法:

// 成功的回调函数
function successCallback(result) {
  console.log("音频文件创建成功: " + result);
}

// 失败的回调函数
function failureCallback(error) {
  console.log("音频文件创建失败: " + error);
}

createAudioFileAsync(audioSettings, successCallback, failureCallback)

现在有了Promise的用法:

createAudioFileAsync(audioSettings).then(successCallback, failureCallback);

2.Promise 的三种状态:pending(未决定),fulfilled(履行),rejected(拒绝)

2.1 pending

初始化状态是pending;
pending 状态不会触发then和catch

2.2 fulfilled

当调用resolve(成功),状态由pending变成fulfilled;
resolved 状态会出发后续的then正确回调函数,而then函数正常会返回resolved,报错会返回rejected

2.3 rejected

当调用reject(失败),状态由pending变成rejected;
rejected状态会触发后续的catch错误回调,而catch政策会返回resolved,报错会返回rejected

3.Promise的优缺点

3.1 优点

(1)支持链式回调,解决回调地狱(Callback Hell)
有时候我们进行一些依赖其他异步操作的异步操作,比如:有多个请求,后一个请求需要上一次请求的返回结果。过去只能一层层callback嵌套,太多的话就行层了回调地狱,而且可维护性差。
(2)更好的进行错误捕获

如果不用promise。多重嵌套的问题,会引发无法捕获异常或异常捕获不可控。

function fetch(callback) {
    setTimeout(() => {
        throw Error('请求失败')
    }, 2000)
}

try {
    fetch(() => {
        console.log('请求处理') // 永远不会执行
    })
} catch (error) {
    console.log('触发异常', error) // 永远不会执行
}

// 程序崩溃
// Uncaught Error: 请求失败

如果使用promise的话,通过reject方法把状态置为rejected,在then就可以捕捉到,然后执行“失败”的回调。

function fetch(callback) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
             reject('请求失败');
        }, 2000)
    })
}


fetch()
.then(
    function(data){
        console.log('请求处理');
        console.log('data',data);
    },
    function(reason, data){
        console.log('触发异常');
        console.log('reason:',reason);
    }
);

截图

3.2 Promise缺点

(1)无法取消Promise,一旦新建它就会立即执行,无法中途取消。
(2)如果不设置回调函数,promise内部抛出的错误,不会反应到外部。—没get到
(3)当处于pending状态时,无法得知目前进展到哪一个阶段(pending还是fulfilled)
(4)Promise真正执行回调的时候,定义Promise那部分实际上已经走完了,所以Promise的报错堆栈上下文不太友好。

4.Promise解决什么问题?

解决了回调地狱,层层嵌套的异步回调函数会使得错误捕获难。

Promise 是一种帮助处理一类特定的异步编程的方式:一个函数(或者方法)异步地返回结果。为了实现这样的函数,需要返回一个 Promise ,它是最终返回结果的一个占位符对象。函数的调用者在 Promise 对象上注册回调,一旦结果计算出来了,就可以收到通知。函数通过 Promise 发送结果。

5.怎么用Promise,什么时候用Promise而不是传统的回调函数?

—当需要多次顺序执行异步操作的时候。

5.1 常见的promise Q&A(FAQ)
Q: then、catch 和 finally 序列能否顺序颠倒?
A: 可以,效果完全一样。但不建议这样做,最好按 then-catch-finally 的顺序编写程序。 
Q: 除了 then 块以外,其它两种块能否多次使用? 
A: 可以,finally 与 then 一样会按顺序执行,但是 catch 块只会执行第一个,除非 catch 块里有异常。所以最好只安排一个 catch 和 finally 块。 Q: then 块如何中断? 
A: then 块默在这里插入代码片认会向下顺序执行,return 是不能中断的,可以通过 throw 来跳转至 catch 实现中断。 
Q: 什么时候适合用 Promise 而不是传统回调函数? 
A: 当需要多次顺序执行异步操作的时候,例如,如果想通过异步方法先后检测用户名和密码,需要先异步检测用户名,然后再异步检测密码的情况下就很适合 Promise。 
Q: Promise 是一种将异步转换为同步的方法吗? 
A: 完全不是。Promise 只不过是一种更良好的编程风格。 
Q: 什么时候我们需要再写一个 then 而不是在当前的 then 接着编程? 
A: 当你又需要调用一个异步任务的时候。

6.Promise和async/await

对于Promise来说,他仍然是个异步操作,返回异步操作的结果。
但是async/await 是不关心是否是异步操作,这就是异步操作的最高境界,将异步强行转换为同步处理。
(1)async/await 与Promise不存在谁取代谁的说法,因为async/await是寄生于Promise,Generater的语法糖。

6.1 async/await用法

(1)async 用于申明一个function是异步的,而await可以认为是async wait(await)的简写,等待一个异步方法执行完成。

  1. async和await是配对使用的,await存在于async的内部,否则会报错。
    2.await表示在这里等待一个promise返回,再执行。
    3.await 后面跟着的应该是一个Promise对象
6.2 try-catch 捕捉

如果是reject 状态,可以用try-catch 捕捉

let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        reject('error');
    },1000);
});

async function demo(params) {
    try {
        let result = await p;
    }catch(e) {
        console.log(e);
    }
}

demo();
6.3 promise和async/await 区别

(1)promise是ES6,async/await是ES7
(2)async/await相对于promise来讲,写法更加优雅
(3)reject状态:promise错误可以通过catch捕捉,建议尾部捕获错误;async/await既可以用.then又可以用try-catch

7.手写Promise

https://juejin.cn/post/6994594642280857630?utm_source=gold_browser_extension

在这里插入图片描述

从这里可以总结出4个Promise的点:
(1)执行了resolve,Promise的状态就会变成fulfilled
(2)执行了reject,Promise的状态就会变成rejected
(3)Promise只以第一次为准,第一次成功就永久为fulfilled,第一次失败就永久成为rejected
(4)Promise中有throw的话,就相当于执行了reject

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值