学会promise和async/await的巧用小妙招

2024-02-01 21:36

本文主要是介绍学会promise和async/await的巧用小妙招,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

因为JavaScript是一种单线程的语言,无法同时执行多个任务。为了解决这个问题,JavaScript引入了Promise和async/await两种方式来处理异步操作。

Promise是一种用于处理异步操作的对象,它可以将异步操作包装成一个对象,通过链式调用的方式来处理异步操作的结果。Promise对象有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当异步操作执行完成后,Promise对象的状态会从pending变为fulfilled或rejected,并且会调用相应的回调函数。

而async/await是ES2017引入的一种用于处理异步操作的语法糖,它是基于Promise的一种更加简洁和可读性更高的异步编程模式。,它基于Promise实现,使得异步代码的编写更加简洁和易读。async函数是一个返回Promise对象的函数,通过在函数前面加上关键字async来声明。在async函数中,可以使用await关键字来等待一个Promise对象的结果,然后将结果赋值给一个变量。

一、Promise

Promise是一种用于处理异步操作的对象。它有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。一个Promise对象可以通过调用resolve方法来转为fulfilled状态,或者通过调用reject方法来转为rejected状态。当一个Promise对象的状态变为fulfilled或rejected时,会触发相应的回调函数。Promise 是 ES6 中引入的一种处理异步操作的方式,它通过 then 和 catch 方法来处理异步操作的结果和错误。

Promise的基本用法如下:

const promise = new Promise((resolve, reject) => {// 异步操作if (异步操作成功) {resolve(结果);} else {reject(错误);}
});promise.then((结果) => {// 处理成功的结果
}).catch((错误) => {// 处理失败的错误
});

Promise 的构造函数接受一个执行器函数作为参数,该执行器函数接受两个参数 resolve 和 reject,分别用于处理异步操作的结果和错误。Promise的优点是可以避免回调地狱(callback hell),即多层嵌套的回调函数。但是在处理多个异步操作时,Promise的链式调用会导致代码冗长且难以维护。这时可以使用async/await来简化代码。

二、async/await

async/await是基于Promise的一种更加简洁和可读性更高的异步编程模式。async函数是返回一个Promise对象的函数,而await关键字用于等待一个Promise对象的结果。

在使用async/await时,我们可以使用try/catch语句来捕获和处理异步操作中的错误。try/catch可以用于捕获await表达式中的错误,以及async函数内部的同步错误。如果在async函数内部没有使用try/catch来捕获错误,错误会被自动地传递给async函数返回的Promise对象的拒绝处理函数。

async函数的基本用法如下:

async function 函数名(参数) {// 异步操作if (异步操作成功) {return 结果;} else {throw 错误;}
}函数名(参数).then((结果) => {// 处理成功的结果
}).catch((错误) => {// 处理失败的错误
});

在async函数中,可以使用await关键字来等待一个Promise对象的结果。await关键字只能在async函数中使用,它会暂停async函数的执行,直到Promise对象的状态变为fulfilled或rejected。

await关键字的基本用法如下:

const 结果 = await Promise对象;

await关键字只能在async函数内部使用,它用于等待一个Promise对象的解析结果。当遇到await关键字时,async函数会暂停执行,直到Promise对象被解析完成并返回结果。

注意,await关键字只能在async函数中使用。如果在非async函数中使用await关键字,会导致语法错误。

async/await的优点是可以使用同步的方式编写异步代码,使得代码更加简洁和易于理解。它可以避免回调地狱,同时也可以处理多个异步操作的并发执行。

三、async/await和Promise的区别

async/await和Promise都是用于处理异步操作的方式,它们之间有以下几点区别:

  1. 语法差异:async/await使用async函数和await关键字来处理异步操作,而Promise使用Promise对象的then和catch方法来处理异步操作。

  2. 错误处理:在async/await中,可以使用try/catch语句来捕获异步操作的错误。而在Promise中,可以使用catch方法来捕获异步操作的错误。

  3. 可读性:使用Promise时,由于需要通过链式调用的方式来处理异步操作的结果,代码会变得比较冗长,可读性较差。而使用async/await时,可以通过在async函数中使用await关键字来等待异步操作的结果,代码更加简洁和易读。async/await相对于Promise来说,代码更加简洁和易于理解。它使用同步的方式编写异步代码,避免了回调地狱。

  4. 并发执行:Promise可以使用Promise.all方法来并发执行多个异步操作,而async/await需要使用Promise的语法来实现。

  5. 使用场景:Promise适用于处理多个异步操作的情况,可以通过链式调用的方式来处理异步操作的结果。而async/await适用于处理单个异步操作的情况,通过在async函数中使用await关键字来等待异步操作的结果。

四、实例演示

  1. 使用Promise实现异步操作
function delay(ms) {return new Promise((resolve) => {setTimeout(resolve, ms);});
}delay(1000).then(() => {console.log('1秒后执行');
});
  1. 使用async/await实现异步操作
async function delay(ms) {await new Promise((resolve) => {setTimeout(resolve, ms);});
}async function run() {await delay(1000);console.log('1秒后执行');
}run();
  1. 并发执行多个异步操作

使用Promise实现:

const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);Promise.all([promise1, promise2, promise3]).then((results) => {console.log(results); // [1, 2, 3]
});

使用async/await实现:

async function run() {const promise1 = Promise.resolve(1);const promise2 = Promise.resolve(2);const promise3 = Promise.resolve(3);const results = await Promise.all([promise1, promise2, promise3]);console.log(results); // [1, 2, 3]
}run();

五、总结

async/await 和 Promise 是 JavaScript 中处理异步操作的两种方式。async/await 是基于 Promise 的语法糖,它可以更方便地编写异步代码。在使用 async/await 时,可以使用 try/catch 语句来处理异步操作的错误。在使用 Promise 时,可以使用 then 和 catch 方法来处理异步操作的结果和错误。

async/await是基于Promise的一种更加简洁和可读性更高的异步编程模式,可以避免回调地狱,使得代码更加简洁和易于理解。

如果只需要处理一个异步操作,可以使用Promise;如果需要处理多个异步操作,可以使用async/await和Promise的组合来实现并发执行。

这篇关于学会promise和async/await的巧用小妙招的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/668533

相关文章

JavaScript Promise技术

你可能已经知道Promises现在已经是JavaScript标准的一部分了。Chrome 32 beta版本已经实现了基本的Promise API。如今,Promise的概念在web开发中已经不是什么新鲜玩意了。我们中的大多数人已经在一些流行的JS库例如Q、when、RSVP.js中使用过了Promises。即使是jQuery中也有一个和Promises很类似叫做Deferred的东西。但是Ja

Rust:Future、async 异步代码机制示例与分析

0. 异步、并发、并行、进程、协程概念梳理 Rust 的异步机制不是多线程或多进程,而是基于协程(或称为轻量级线程、微线程)的模型,这些协程可以在单个线程内并发执行。这种模型允许在单个线程中通过非阻塞的方式处理多个任务,从而实现高效的并发。 关于“并发”和“并行”的区别,这是两个经常被提及但含义不同的概念: 并发(Concurrency):指的是同时处理多个任务的能力,这些任务可能在同一时

Exception processing async thread queue Exception processing async thread queue

错误信息描述: eclipse 在debug中弹出异常信息框 Exception processing async thread queue Exception processing async thread queue 解决方法: eclipse 中有一个Expressions窗口,里面添加的 expression 没有正确执行,并且没有删除,只要 Remove All Expressio

九分钟学会 Markdown

转自:http://dapengde.com/archives/17033 技多不压身。如果你愿意花九分钟学一个当前流行的软件技术的话,可以开始计时了。 00:00 是什么以及为什么 Markdown 是一种轻量级标记语言。好吧,我承认这不是人话。换个说法:Windows 里的记事本或办公软件 Word 你用过吧?类似的,Markdown 软件是用来在电脑里写文字的(作文、笔记、会

【Android逆向】小白也能学会的一个小时破解某猫社区VIP会员

第二步:使用 dex2jar 将 classes.dex 转成 jar 文件 cmd到dex2jar文件夹目录,执行 d2j-dex2jar D://xxx/xxx/classes.dex 得到 jar 文件 静态分析 拿到源码后,首先我们需要找到应用的限制点,绕过App里面的判断。 然后分析源码,该从哪里开始入手呢? 我们都知道,一个完整Android应用,可能会存在各

Matlab中巧用LaTex

Matlab图形中title、xlabel、ylabel、zlabel、textbox和legend等的Interpreter属性有三个属性:latex 、tex、none。默认为tex。 当键入:>> set(text,'Interpreter') Matlab将返回'Interpreter'所包含的属性值: [ latex | {tex} | none ]。 利用Matlab文本的Interp

解析Java中1000个常用类:AbstractSequentialList类,你学会了吗?

推荐一个我自己写的小报童专栏导航网站: http://xbt100.top 收录了生财有术项目精选、AI海外赚钱、纯银的产品分析等专栏,陆续会收录更多的专栏,欢迎体验~复制URL可直达。 以下是正文。 在 Java 集合框架中,AbstractSequentialList 是一个重要的抽象类,为实现自定义的顺序列表提供了基础结构和默认实现。 作为 java.util 包中的一部分,Ab

学懂C#编程:常用高级技术——学会Lambda表达式的应用(二)

上一篇介绍了Lambda基础的知识,接着我们通过讲解Lambda的几种应用场景来彻底学懂Lambda在编程中的应用。 Lambda表达式在C#中非常灵活,可以用在多种场合。以下是一些Lambda表达式示例,帮助你更全面地理解其用途: 1. 数组过滤(使用Where) int[] numbers = { 1, 2, 3, 4, 5, 6 };var evenNumbers = numbers

Python协程探秘:async/await的魔法

Python协程探秘:async/await的魔法 在Python的并发编程世界中,协程(Coroutines)和async/await关键字正逐渐崭露头角,它们提供了一种高效、轻量级的并发解决方案。本文将深入解释协程的概念,探讨async/await关键字的作用,并通过示例展示如何在Python中使用它们。 一、协程简介 协程,又称为微线程(Microthreads)或用户态线程(User

【Rust日报】 2019-05-30:使用最新的 async/await 的一些例子

一个说明借用/Move细节的鲜活例子 如下面例子,直接传一个元组进去,不行。索引里面的元素,直接传,可以。为什么? fn f(input: (usize, &mut usize)) {unimplemented!()}fn call_f_a_bunch_of_times(input: (usize, &mut usize)) {for _ in 0..10 {// f(input); //