Promise和async_await

文章介绍了JavaScript中处理异步操作的常见方法,从回调函数的概念和可能导致的回调地狱问题,过渡到Promise的使用,包括then、catch和finally的链式处理。接着,文章探讨了async/await的引入,作为简化异步代码的语法糖,使得异步操作更易读和管理。最后,通过比较Promise和async/await处理异步操作的例子,突显了async/await的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.回调函数

这一章教你如何做一个时间管理大师
我们试想一个排队办手续的场景,在轮到你之前,你可以玩手机,可以和朋友聊天,等等。可以做很多很多事情。这样就可以成功的打发这段排队等候的无聊时光,同时做好自己的事情,同时也不影响排队的进程。这样的过程和异步处理 的原理有点相似。

般来说,异步处理常常用于处理那些需要较长时间才能完成的操作,例如从服务器上获取数据、读取文件、进行网络请求等。如果使用同步处理,程序就会一直等待这些操作的完成,造成程序的阻塞。而使用异步处理,则可以充分利用程序的资源,同时处理其他任务

于是我们便引入了回调函数

setTimeout(function(){   
	console.log('执行了回调函数');
},3000)  //3000毫秒

我们让程序等个3000毫秒,之后自动执行
很好,3000毫秒以后执行就很合适。

但是在项目中不可能只有一个进程需要处理

        setTimeout(function () {  //第一层
            console.log('清早起来');
            setTimeout(function () {  //第二程
                console.log('真tm的困啊');
                setTimeout(function () {   //第三层
                    console.log('腰酸腿疼脖子硬');
                  							.......//好多好多层
                }, 1000)
            }, 2000)
        }, 3000)

这玩意就被称为**回调地狱,**推断个语法累死你

2.Promise

1.then.catch.finally的用法

在ES6中,引入了Promise这个概念,你可以把它类比为一个if-else语句
执行成功了怎么样,失败了怎么样

下面开始正文:
Promise原本的状态是_pending(初始状态)
当执行成功完成之后,状态从pending变成了
fulfilled(已对现),之后我们实行那些操作。
当执行操作失败之后,状态从pending变成了reject
(已拒绝)_,之后我们实行那些操作。
我们写一个案例
先翻译下,resolve是解决的意思,reject是拒绝的意思。

var myPromise = new Promise((resolve, reject) => {
  // 执行异步操作
  if (/* 异步操作成功 */) {
    resolve(value); // pending -> fulfilled
  } else {
    reject(error); // pending -> rejected
  }
});

myPromise
  .then(value => {
    // 成功处理异步操作的结果
  })
  .catch(error => {
    // 处理异步操作失败的情况
  })
  .finally(() => {
    console.log('执行完毕');
  });

也就是说,异步操作最终肯定只有两个结果,要么成功要么失败,这个叫Promise的东西,会带着**成功(resolve)或者失败(reject)**的信息一起返回

  • 如果带回来的是成功的信息,那就会执行后面程序中then()里面的代码。
  • 如果带回来的是失败的信息,那就会执行后面程序中catch()里面的代码。
  • 不论是成功还是失败,都会输出finally里面的东西。

当然了,上面的catch也不是必须的,你也可以这么写

var p = new Promise((resolve,reject)=>{
 //主动调用reject,并传入实参2
   reject(2)
})
// 此时,P的状态是rejected,且值promiseValue 是2.
p.then((res)=>{
   // p的状态是resolved
   // 所以这句代码不会执行。
   console.log("then,ok",res)
},(err)=>{
 // p的状态是rejected
 // 执行then的第二个参数
 // 并把promisevalue传进来。
    console.log("then,err",err)
})

2.链式处理

then返回的也是一个_fulfilled/reject值得,就是是否对现_

// 方法
function todo1() {
        console.log("一");
    }


    function todo2() {
        console.log("二");
      	console.log(a); //这里的a没有定义,会报错
    }


    function todo3() {
        console.log("三");
    }


    function todo4() {
        console.log("四");
    }


// 执行操作
    var p = new Promise((resolve, reject) => {
        resolve()
    })
// 分别调用方法
    p.then(todo1)
        .then(todo2)
        .then(todo3)
        .catch(todo4);

输出结果:一,二,四

流程:
p里面写的是resolve,那直接执行第一个then里面的代码。成功后返回resolve,可以进入第二个then(todo2)。
进入todo2中,console.log(“二”);先执行,但是由于a没有定义(通常情况下要写一个**var a;再写console.log(a);**但是这里没有写)执行失败,返回reject,这样就没法继续执行then,因为then必须要操作成功返回resolve才能进入,既然语句操作失败,那只能进入catch中,执行todo4,todo3不执行,直接输出4。

想要详细了解的朋友,点击这里:Promise

3.async/await

在刚刚提到的链式中,我们发现上面写的简单,但是理解起来超级麻烦,于是我们引入了async/await
这个是方便处理链式的一个语法糖
(语法糖就是原来使用一大串代码才能使用的东西,现在只需要把语法糖丢进去就可以使用,减少代码量)
他的基本写法是这样的

//这一段方法不用看
function fn() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

//看这里!!!
//1.async就是异步函数的一个标志
//2.await就是等待fn()这个函数执行完,执行完成后会返回一个promise值,也就是执行成功resolve或者失败reject
async function asyncCall() {
  console.log('calling');
  const result = await fn();
  console.log(result);
  // Expected output: "resolved"
}

1.async就是异步函数的一个标志
2.await就是等待fn()这个函数执行完,执行完成后会返回一个promise值,这个值的内容就是执行成功:resolve或者失败:reject。

好像也看不出来好在哪里,但是要是作用于链式,那就牛了
举个例子

// 使用 async/await 处理异步操作
async function getDataWithAsync() {
  try {
    // 使用 await 关键字等待 fetch 方法返回的 Response 对象
    // 说人话就是看看这个链接请求成功了没
    const response = await fetch('https://api.example.com/data');
    // 使用 await 关键字等待 Response 对象的 json 方法返回的 Promise 对象
    // 说人话就是看看response转化成.json了没
    const data = await response.json();
    // 如果上面的都成功了(await返回resolve),输出这一句
    console.log(data);
  } catch (error) {
    // 如果上面的await返回的是reject,失败了,就输出这一句
    console.error(error);
  }
}


// 使用 Promise 处理异步操作
function getDataWithPromise() {
  // 使用 fetch 方法发送 HTTP 请求并返回 Promise 对象
  fetch('https://api.example.com/data')
    // 使用 then 方法注册回调函数处理 Response 对象
    .then(response => response.json())
    // 使用 then 方法注册回调函数处理 JSON 数据
    .then(data => console.log(data))
    // 使用 catch 方法捕获错误并输出错误信息
    .catch(error => console.error(error));
}

注意,第二段代码里面没有写promise,但是fetch返回的值是promise类型,也就是成功或失败,想要详细了解可以看这里:fetch()

### JavaScriptPromiseAsync/Await 的概念及用法 #### 一、Promise 基础 Promise 是一种用于处理异步操作的对象,它表示一个最终完成或失败的操作,并返回其结果。通过 `then()` 方法可以获取成功的结果,`catch()` 可以捕获错误。 以下是基本的 Promise 结构: ```javascript const myPromise = new Promise((resolve, reject) => { if (/* 条件 */) { resolve("成功"); } else { reject("失败"); } }); myPromise .then(result => console.log(result)) // 处理成功的回调 .catch(error => console.error(error)); // 处理失败的回调 ``` 这种模式解决了传统的回调地狱问题[^3],使得代码更加清晰易读。 --- #### 二、Async/Await 的引入及其优势 Async/Await 是基于 Promise 构建的一种更简洁的异步编程方式。它可以将复杂的链式调用转化为同步风格的代码结构,从而提升可维护性可读性。 ##### 定义 Async 函数 使用 `async` 关键字声明的函数总是返回一个 Promise 对象。如果该函数内部抛出异常,则会触发 Promise 的拒绝状态。 示例代码如下: ```javascript async function fetchData() { try { let result = await someAPICall(); // 等待 API 调用完成 console.log(result); } catch (error) { console.error("发生错误:", error); // 捕获并处理错误 } } ``` 上述代码中的 `await` 表达式的求值过程会被暂停直到对应的 Promise 履行完毕或者被拒绝为止[^2]。 --- #### 三、从 `.then/.catch` 到 Async/Await 的转换 假设有一个简单的 Promise 链: ```javascript function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } delay(1000).then(() => { console.log('等待了一秒钟'); }).catch(err => { console.error(err); }); ``` 将其改写为 Async/Await 形式后显得更为直观: ```javascript async function runDelay() { try { await delay(1000); console.log('等待了一秒钟'); } catch (err) { console.error(err); } } runDelay(); ``` 可以看到,在逻辑上两者完全一致,但是后者消除了层层嵌套的问题。 --- #### 四、两者的对比总结 | 特性 | **Promise** | **Async/Await** | |---------------------|------------------------------------|-----------------------------------| | 是否支持链式调用 | 支持 | 不直接支持 | | 错误处理 | 使用 `.catch()` | 使用 `try...catch` | | 编码风格 | 更加显式 | 类似于同步代码 | | 学习曲线 | 较陡峭 | 相对平缓 | 尽管它们都属于非阻塞型机制,但在实际开发过程中推荐优先选用 Async/Await,因为它不仅简化了语法规则还增强了程序的表现力。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值