js之promise

本文讲述了JavaScript单线程环境下的事件阻塞问题,介绍了如何通过异步编程(如Promise和async/await)避免阻塞,以及Promise的三种状态、API(如resolve、reject、then、catch和race)的使用。文章还讨论了Promise在处理异步操作、避免回调地狱、错误处理和组合操作中的作用。
摘要由CSDN通过智能技术生成

事件阻塞
由于js是单线程模式,所有的js代码都在一个主线程上执行,当主线程正在执行一个长时间运行的操作时,它就无法同时处理其他事件的请求了,如果js是多线程,那么不同的线程可能会同时修改同一个变量,从而导致不可预料的结果。为了避免事件阻塞,采用异步编程的方式,使用异步API和回调函数来处理长时间运行的操作。
异步编程的原理,将长时间运行的操作放到一个单独的线程中执行,在操作完成后,将结果传递给js主线程进行处理。这样可以避免长时间运行的操作阻塞js主线程,保证页面的响应性能。

Promise
Promise是一种用于异步编程的js对象,它可以解决回调地狱的问题,并提供更好的代码可读性和可维护性。Promise可以看作一种承诺,表示在未来某个时间点会返回一个结果,这个结果可以是成功的,也可以是失败的。

三种状态:
1、Pending(等待状态): Promise对象刚被创建时的初始状态,此时还没有返回结果。
2、Fulfilled(成功状态):当Promise对象返回结果时,进入成功状态,并把结果作为参数传递给后续的then方法。
3、Rejected(失败状态):当Promise对象返回错误结果时,进入失败状态,并把错误信息作为参数传递给后续的catch方法

API

  • Promise.resolve()
  • Promise.reject()
  • Promise.prototype.then
  • Promise.prototype.catch
  • Promise.race
let downloadCancelled = false;
const cancelDownload = () => {
  downloadCancelled = true;
};
const downloadFile = new Promise((resolve, reject) => {
  // 下载大文件
});
const cancel = new Promise((resolve, reject) => {
  while (!downloadCancelled) {
    // 等待用户点击取消按钮
  }
  resolve('Download cancelled');
});
Promise.race([downloadFile, cancel]).then(result => {
  console.log(result); // 下载已取消
}).catch(error => {
  console.error(error); // 下载错误
});
  • Promise.all
    async/await
    在promise异步编写方式进一步升级,更靠近同步编写方式
function ff (){
  return new Promise((resolve,reject)=>{
    ....
  })
}
async function test(){
  let res = await ff()
}
test()

Promise 异常穿透与错误处理

// catch 等价于 =>
Promise.prototype.then(undefined, onRejected)

.then 对比 .catch

promise.then(f1).catch(f2);
promise.then(f1, f2);

两者不相等,不同之处在于,如果 f1 中出现 error,那么在第一个链式调用中,error 会被 catch 捕获,并在 f2 中被处理,但是在第二种写法中不会,这是因为 error 是沿着链传递的,而在第二段代码中,f1 和 f2处于同一层级,二者只会执行其一,下面没有链,所以 error 不会被处理。

new Promise((resolve, reject) => {
    reject('失败了')
})
    .then(
        (data) => { console.log('onResolved1', data); },
        (error) => { console.log('onRejected2', error); }
    )
    .catch(
        (error) => {
            console.log('catch', error)
        }
    )

"失败了" 就会被离它最近的 then 中的 onRejected 函数所处理,而不会被 catch 所捕获。

异步回调中的错误无法捕获
定时器这种异步中的错误,promise 捕获不到的

new Promise((resolve, reject) => {
    setTimeout(() => {
        throw new Error("Whoops!");
    }, 1000);
})
    .catch(error => {
        console.log('catch error:', error);
    });

executor 中的异步错误解决方案
在 executor 执行器中,不管最终拿到什么结果,建议都使用 resolvereject 去接收

// 直接使用 reject 接收 error
new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error("Whoops!"))
    }, 1000);
})

也可以先用 try...catch 捕获 throw 出的 error,然后用 reject 去接收。

new Promise((resolve, reject) => {
    setTimeout(() => {
        try {
            throw new Error("Whoops!");
        } catch(error) {
            reject(error)
        }
    }, 1000);
})

中断promise
返回一个状态一直为 pending 的 promise

.catch((err) => {
  console.log('onRejected', err);
  // 中断promise链:
  return new Promise(() => {})
})

Promise的作用是什么
Promise是一种用于异步编程的JavaScript对象,它可以解决回调地狱的问题并提供更好的代码可读性和可维护性。

  1. 处理异步操作:在JavaScript中,异步操作比如Ajax请求、定时器等是很常见的,它们不能立即得到结果,而是需要等待一段时间才能得到结果。使用Promise可以方便地处理异步操作,避免阻塞UI线程,提高页面响应速度。
  2. 避免回调地狱:在传统的回调函数中,如果有多个异步操作需要执行,嵌套的回调会导致代码难以阅读和维护。而Promise通过链式调用的方式,可以避免这种嵌套的情况,使得代码更加清晰易懂。
  3. 提供更好的错误处理:Promise提供了catch方法来处理异常情况,使得代码更加健壮和可维护。在Promise中,任何一个操作的错误都可以在catch方法中捕获并进行处理,从而避免了在回调函数中抛出异常导致程序崩溃的情况。
  4. 便于组合操作:使用Promise可以方便地组合多个异步操作,使得代码更加简洁和可读性更强。例如,我们可以使用Promise.all方法来并行执行多个异步操作,并在所有操作完成后进行下一步处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值