JavaScript期约 异步编程 Promise Async Await ES6

Promise

期约是为了简化异步编程而设计的语言特性。使用new Promise()构造函数可以新建一个期约,该函数接收一个函数作为参数,我们先传入一个空函数:

const p=new Promise(()=>{})
console.log(p)
// out: Promise { <pending> }

上述输出表示期约的状态,目前为pending。

上面的函数参数又可以接收如下两个函数参数:

  • resolve() : 可将期约的状态变为resolved。
  • reject() : 可将期约的状态变为rejected。

如下示例将期约变为resolved状态:

const p=new Promise((resolve,reject)=>resolve(' Promise Value '))
console.log(p)
// 输出:Promise {' Promise Value '}

这个输出表示期约的值是’ Promise Value ',没有标明状态就是默认resolved。

如下示例将期约变为rejected状态:

const p=new Promise((resolve,reject)=>reject(' Promise Rejeted Value '))
console.log(p)
// 输出: Promise { <rejected>  ' Promise Rejeted Value '}

这个输出结果表示期约当前的状态是rejected,期约值是’ Promise Rejeted Value '。同时,此时控制台会输出一些错误信息。

通过打印期约对象,我们可以发现,期约分为三种状态:pending、resolved 和 rejected。

期约的状态决定了后续的操作是调用then()还是调用catch()。期约值是期约链式操作的数据流转的第一步。

除了构造函数以外,可以使用如下方式快速创建期约:

const  p1= Promise.resolve(' Promise Value ')
console.log(p1)
// out:Promise {' Promise Value '}

const  p2= Promise.reject(' Promise Rejeted Value ')
console.log(p2)
//out: Promise { <rejected> ' Promise Rejeted Value ' }

期约方法和期约链

多层串联的回调函数本质上是多个函数的链式操作,上一个函数的返回值作为参数传递给下一个函数,使用期约对象的then()方法,就能实现链式操作,例如:

const p = Promise.resolve(1)

p
.then(x=>x+1)
.then(x=>x*2)
.then(x=>console.log(x))   //=>4

期约对象的链式操作有三个方法:then()、catch()、finally()。这三个方法都接收一个函数作为参数,表示下一步的操作。

当期约对象的状态变为resolved时,就可以调用then(),例如:

const p = Promise.resolve(1)
p
.then(x=>x+1)
.then(x=>x*2)
.then(x=>console.log(x))   //out:4

当期约对象的状态变为rejected时,就可以调用catch(),不过,一次正常的catch()之后,状态就会变为resolved,例如:

const p= Promise.reject(1)
p
.catch(x=>x+1)
.then(x=>x*2)
.then(x=>console.log(x))   //out:4

期约对象无论是什么状态,都可以调用finally()。如下:

const p= Promise.reject(1)
p
.finally(()=>console.log('Promise Chain Start!'))
.catch(x=>x+1)             
.then(x=>x*2)
.then(x=>console.log(x))
.finally(()=>console.log('Promise Chain Stop!'))  

期约链是一个串行操作,像流水线一样,每道工序可能包含:自己的操作、流转的数据,如果不显式或隐式地使用return为下一个操作提供数据,那么该步操作会直接将上一步的数据流转到下一步。

也就是说,每一步肯定有一个流转数据,就看你用不用、处不处理,每一步也肯定会输出流转数据到下一步。流转的数据就是每一步都回调函数的第一个参数,如下示例:

const p= Promise.resolve(1)        
p
.then((x)=>console.log('Promise Chain Start!'))
.then(x=>{ return 6; })
.then(x=>x*2)                      
.then((x)=>console.log('Now Promise Value is' , x))  // out: 12

在上面这个例子中,由Promise.resolve()产生期约链条的流转数据,每一步的操作其实就是一个箭头函数,箭头函数的第一个参数是流转的数据,函数体是对流转数据的处理或其它行为,第一个then()没有对流转数据进行处理,所以直接往下传递。第二个then()对流转数据进行处理,但是显式地return 6,此时流转数据就是6。第三个then()对流转数据乘以2,注意,根据箭头函数的规则,这一行其实隐式地return了12。最后一个then()是获取流转数据并输出。

由上面的几个例子还可以看出,期约的链式操作是打平的,解决了以往的回调函数层层嵌套的问题,写法上更直观,理解起来也更直接。

async和await

async和await是ES2017推出的异步函数关键字,可以看做是Promise的语法糖。把函数声明为async意味着该函数的返回值将会是一个resolved状态的期约:

async function foo(){
      return 'Promise Value'
      // 等价于:
     // return Promise.resolve('Promise Value')
}
console.log(foo())  
//  out:Promise { 'Promise Value' }

await的作用是取出期约对象中的值,同时告诉编译器异步执行后面的任务。注意,await只能定义在async函数的内部:

async function foo(){
        return  'Promise Value'
}

async function bar(){
        // 取出期约对象的值
        const result = await foo()
        console.log(result)
}

bar()

ES2022标准推出了顶层await特性。async定义的函数依然是同步求值的,await关键字才是真正的异步。

以往,await只能写在async函数里面,ES2022新增了顶层await特性,允许await在函数外面书写。要在node环境中测试最新(ES2022)的顶层await特性,需要将后缀名改为mjs。

ES6中的async和await是用于处理异步操作的关键字。async关键字用于声明一个函数是异步的,而await关键字用于等待一个异步任务执行完成。 通过使用async和await,我们可以以同步的方式编写异步代码,使得代码更加清晰和易读。 使用async关键字声明的函数会返回一个Promise对象。在函数内部,我们可以使用await关键字来等待一个异步任务执行完成,而不需要使用回调函数或者Promise的then方法。当await关键字等待一个异步任务时,它会暂停函数的执行,并且等待异步任务完成后继续执行函数。 async和await的使用可以大大简化异步代码的编写,使得代码更易于理解和维护。它们是ES6中非常有用的特性,被广泛应用于JavaScript开发中。 引用: 目录 ES6async和await关键字1、初步了解2、async关键字3、await关键字4、深入讲解async和await。 :主要介绍了详解ES6async await 同步/异步方案,本文以最简明的方式来疏通 async await,有兴趣的可以了解下。 :我们先从字面意思来理解这两个关键字,asyncasynchronous(异步)的简写,而await可以认为是async wait的简写。所以async可以理解为用于声明一个函数是异步的,而await用于等待一个异步任务执行完成。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [详解ES6async和await关键字](https://blog.csdn.net/ldjgood/article/details/123696983)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [详解ES6async+await 同步/异步方案](https://download.csdn.net/download/weixin_38746166/12772472)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值