Adakah async merupakan atribut es6?

青灯夜游
Lepaskan: 2023-01-11 15:36:37
asal
1795 orang telah melayarinya

milik, async ialah ciri baharu es6, yang digunakan untuk menunjukkan bahawa mungkin terdapat proses tak segerak dalam atur cara. Fungsi yang diisytiharkan dengan kata kunci async mengembalikan objek Promise Jika nilai langsung dikembalikan dalam fungsi, async akan merangkum nilai langsung ke dalam objek Promise melalui Promise.resolve( apabila fungsi async tidak mengembalikan nilai, ia mengembalikan " Promise.resolve(undefined)".

Adakah async merupakan atribut es6?

Persekitaran pengendalian tutorial ini: sistem Windows 7, ECMAScript versi 6, komputer Dell G3.

Ciri baharu ES6 tidak segerak dan menunggu kata kunci

1 Pemahaman awal

Mari kita fahami ini secara literal Dua kata kunci, async ialah. singkatan asynchronous (asynchronous), dan menunggu boleh dianggap sebagai singkatan async wait. Jadi async boleh difahami sebagai digunakan untuk mengisytiharkan fungsi sebagai tak segerak, manakala await digunakan untuk menunggu tugas tak segerak selesai.

Kata kunci tak segerak dan menunggu membolehkan kami menulis gelagat tak segerak berdasarkan janji dengan cara yang lebih ringkas tanpa sengaja merantai janji.

Seterusnya, mari kita lihat awal pada fungsi async dan tunggu melalui beberapa contoh.

Titik pengetahuan 1: Fungsi yang diisytiharkan dengan kata kunci async mengembalikan objek Promise. Jika terdapat pembolehubah langsung dalam fungsi, async akan merangkum pembolehubah langsung ke dalam objek Promise melalui return. Apabila fungsi Promise.resolve() tidak mempunyai nilai pulangan, ia mengembalikan asyncPromise.resolve(undefined)

 //定义一个普通函数,返回一个字符串
 function test() {
     return "hello async";
 }
 const result1 = test();
 console.log(result1); //输出一个字符串 hello async
 
 //定义一个使用了async修饰的函数,同样返回一个字符串
 async function testAsync() {
     return "hello async";
 }
 const result2 = testAsync();
 console.log(result2); //输出一个Promise对象 Promise {<fulfilled>: 'hello async'}
Salin selepas log masuk
 //async较好的用法
 async function testAsync(){
     //返回一个Promise对象
     return new Promise((resolve, reject)=>{
         //处理异步任务
         setTimeout(function () {
             resolve("testAsync")
         }, 1000);
     })
 }
 //async通常用于声明一个处理异步任务且返回了Promise对象的函数
Salin selepas log masuk

Titik pengetahuan 2: Kata kunci await hanya boleh digunakan dalam fungsi yang diisytiharkan sebagai tak segerak . Digunakan untuk mengubah suai objek Promise supaya tugas tak segerak yang diproses oleh objek Promise dilaksanakan secara serentak dan berjujukan pada coroutine semasa.

 //定义一个使用async修饰的函数,处理异步任务
 async function testAsync(){
     return new Promise((resolve, reject)=>{
         setTimeout(function () {
             resolve("testAsync")
         }, 1000);
     })
 }
Salin selepas log masuk
 //定义一个函数,直接调用testAsync函数
 function testAwait(){
     console.log('testAsync调用前')
     testAsync().then(res=>{
         console.log(res) //输出"testAsync"
     })
     console.log('testAsync调用后')
 }
 
 /***** 输出如下 *****/
 testAsync调用前
 testAsync调用后
 testAsync
 //尽管代码按顺序写,但不按顺序执行,因为testAsync()是异步函数
Salin selepas log masuk
 //定义一个函数(不使用async声明该函数)用await修饰调用testAsync函数
 function testAwait(){
     console.log('testAsync调用前')
     await testAsync().then(res=>{ //使用await关键字修饰
         console.log(res)
     })
     console.log('testAsync调用后')
 }
 
 //调用testAwait()函数
 testAwait()
 //报错:Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules,因为await只能使用在被async修饰的函数内。
Salin selepas log masuk
 //定义一个函数(使用async声明该函数)用await修饰调用testAsync函数
 async function testAwait(){
     console.log('testAsync调用前')
     await testAsync().then(res=>{
         console.log(res)
     })
     console.log('testAsync调用后')
 }
 
 /***** 输出如下 *****/
 testAsync调用前
 testAsync
 testAsync调用后
 
 //使用了await关键字修饰,使得代码按照顺序执行,即同步执行
Salin selepas log masuk

2. kata kunci async

(1) digunakan untuk menunjukkan bahawa mungkin terdapat proses tak segerak dalam program

(2) Jenis nilai pulangan fungsi async ialah objek Promise: Ini pada asasnya berbeza daripada fungsi biasa, dan ia juga merupakan perkara utama yang perlu diberi perhatian apabila menggunakannya

    kembali newPromise(), ini Penggunaannya selaras dengan tujuan asal fungsi async
  • mengembalikan data, terutamanya ambil perhatian bahawa penulisan seperti ini bersamaan dengan Promise.resolve(data) . Data yang dikembalikan dikapsulkan ke dalam objek Promise, tetapi apabila fungsi async dipanggil, ia adalah semata-mata = tidak boleh mendapatkan data nilai pulangan ini, kerana nilai pulangan ialah objek Promise, jadi anda perlu menggunakan .then(data => ; { }) untuk mendapatkan data ini;
  • Jika tiada Nilai pulangan, bersamaan dengan Promise.resolve(undefined); : Jika terdapat proses tak segerak dalam fungsi yang diisytiharkan menggunakan kata kunci async, ia mungkin menunggu, tetapi fungsi itu sendiri Ia akan kembali serta-merta dan tidak akan menyekat utas utama semasa. Jika proses tak segerak yang diubah suai dengan kata kunci await digunakan dalam fungsi, ia akan berfungsi pada coroutine yang sepadan dan akan menyekat dan menunggu tugas tak segerak selesai sebelum kembali.

3. tunggu kata kunci

 //定义一个函数,处理异步任务(使用定时器模拟),返回一个Promise对象
 async function testAsync(){
     return new Promise((resolve, reject) => {
       setTimeout(function () {
         resolve("成功调用testAsync")
       }, 1000);
     });
 }
 
 //定义一个函数,使用await关键字修饰调用testAsync()函数
 async function testAwait(){
     //使用了await关键字修饰调用testAsyn()函数
     await this.testAsync().then(res=>{
       console.log(res) //输出的是testAsync()函数resolve的值
     });
     console.log("helloAsync");
 }
 
 //主线程
 console.log('testAwait调用前')
 testAwait();
 console.log('testAwait调用后')
 
 /***** 输出结果如下 *****/
 testAwait调用前
 testAwait调用后 //因为testAwait()函数使用了async关键字修饰,所以不会阻塞主线程的执行,所以这两句话会先直接输出,然后再执行testAwait()函数
 成功调用testAsync //因为testAwait()函数在内部调用testAsync()函数时使用了await关键字修饰,所以在对应的协程上会阻塞,等待testAsync()函数执行完,再输出下面那句'helloAsync'
 helloAsync
Salin selepas log masuk

(1) await hanya boleh digunakan di dalam fungsi async: ia tidak boleh diletakkan di dalam fungsi biasa, jika tidak, ralat akan berlaku dilaporkan. (2) Kata kunci await diikuti dengan objek Janji. Jika ia diikuti dengan fungsi, fungsi ini harus mengembalikan objek Promise. Jika ia diikuti oleh objek bukan Janji, ia akan dibungkus secara automatik ke dalam objek Janji melalui fungsi Promise.resolve() dan diletakkan dalam keadaan dipenuhi.

(3) Intipati penantian ialah menunggu status terpenuhi bagi objek Janji yang diubah suai dan mengembalikan data penyelesaian(data).

bermakna jika menunggu diikuti oleh objek
 //例如:
 const a = await 'Hello Await'
 // 相当于
 const a = await Promise.resolve('Hello Await');
 
 console.log(a) //输出 'Hello Await'
Salin selepas log masuk
,

akan menyekat kod berikut, tunggu objek

, dan kemudian dapatkan nilai Promise sebagai await Hasil ungkapan. Promiseresolveresolve (4) await tidak mempedulikan status ditolak objek Janji yang diubah suai, iaitu data data penolakan (data) tidak akan diproses oleh await, jadi disyorkan untuk panggil tangkapan melalui objek Janji untuk menangkapnya . await

 async function testAsync(){
     return new Promise((resolve, reject) => {
       setTimeout(function () {
         resolve("成功调用testAsync")
       }, 1000);
     });
 }
 
 const a = await testAsync() //这里的a就会拿到testAsync函数resolve的数据
 console.log(a) //在一秒后输出'成功调用testAsync'
Salin selepas log masuk

4 Penjelasan mendalam tentang tak segerak dan tunggu

 async testAwait(){
     //变量a用于接收testAsync()函数resolve的数据
     let a = await testAsync().catch(err=>{
         //处理异常和reject的数据
     })    
 }
Salin selepas log masuk

(1) Urutan pelaksanaan

①Cetak keluaran dahulu 🎜>, Kod segerak, dilaksanakan secara berurutan;

② Kemudian panggil kaedah getResult( ), cetakan
 //定义一个函数,该函数接收一个参数,1s后再返回参数的两倍
 async function double(num) {
     return new Promise((resolve, reject) => {
         setTimeout(() => { //使用定时器模拟异步任务
             resolve(2 * num) //将运算结果交给resolve
         }, 1000);
     })
 }
 
 async function getResult () {
     console.log('double调用前')  //顺序:2
     let result = await double(10); //将10作为参数传递给double函数
     //result变量用于接收double()函数resolve的值
     console.log(result); //顺序:4
     console.log('double调用后') //顺序:4
 }
 
 console.log('getResult调用前') //顺序:1
 getResult();
 console.log('getResult调用后') //顺序:3
 
 /***** 依次输出如下 *****/
 getResult调用前
 double调用前
 getResult调用后
 20 //1s后输出
 double调用后
Salin selepas log masuk
, kod segerak, dilaksanakan secara berurutan;

getResult调用前

Jika kata kunci await tidak digunakan di sini, output dalam urutan ialah: sebelum getResult dipanggil, sebelum double dipanggil, selepas double dipanggil, selepas getResult dipanggil, dan 20 adalah output selepas 1s

double调用前Oleh kerana operasi tak segerak Ia tidak akan menjejaskan pelaksanaan kod lain, jadi kod lain akan dilaksanakan mengikut tertib, dan akhirnya fungsi berganda

akan dilaksanakan kerana kata kunci await digunakan di sini, jadi kod getResult() dilaksanakan Ia akan disekat di sini, tunggu sehingga fungsi berganda diselesaikan, dan kemudian laksanakannya

④尽管getResult函数内部被await阻塞了,由于getResult函数本身也是个async函数,所以它不会影响getResult函数外面的代码执行。因为调用async函数不会造成阻塞,它内部的所有阻塞都被封装在一个Promise对象中异步执行。

⑤所以在调用getResult函数后,会继续向下执行,即打印输出getResult调用后

⑥当1s之后,异步函数double执行完成,将结果交给resolve。

⑦通过await关键字接收到double函数resolve的值,赋值给result变量。打印输出20

⑧因为使用了await阻塞将异步变为同步,所以在打印输出20后再打印输出double调用后

(2)处理reject回调

 //方法一:通过promise对象的catch进行捕获
 function a(){
     return new Promise((resolve,reject) => {
         setTimeout(() => {
             reject("something")
         }, 1000)
     })
 }
 
 async function b(){
     let r = await a().catch((err)=>{
         console.log(err)
     })
 }
Salin selepas log masuk
 //方法二:通过try/catch语句处理
 function a(){
     return new Promise((resolve,reject) => {
         setTimeout(() => {
             reject("something")
         }, 1000)
     })
 }
 
 async function b(){
     let r = null
     try{
        r = await a()
     }catch(err){
         console.log(err)
     }
 }
Salin selepas log masuk

(3)使用await优化Promise对象的回调地狱问题

在Promise章节中我们通过了Promise对象的then( )方法链式调用解决了回调地狱问题,但看起来仍然不够美观,我们可以通过await优化一下,让它看起来更符合我们平时代码的编写习惯。

 //原本的解决方案
 //第二个请求依赖于第一个请求的返回值,第三个请求依赖于第二个请求的返回值
 request1().then(function(data){ 
     return request2(data)
 }).then(function(data){ 
     return request3(data)
 })
 //这里只发送了三次请求,代码看起来还不错,虽然它已经比普通的回调函数形式好了很多。
 //那如果需要发送五次或十次请求呢?代码也许会没那么美观,接下来我们使用学习到的await去解决这个问题。
Salin selepas log masuk

原本的要求是每个请求都依赖于上一个请求的返回值,那么是不是得等一个请求完,才能发送下一个请求?这时我们可以思考一下,await的作用是什么?是不是对一个Promise对象去进行阻塞,使其状态变为fulfilled后获取resolve的值。这不就正是我们所需要的。

 //使用await的解决方案
 var res1 = await request1() //将request1的返回值赋值给res1
 var res2 = await request2(res1) //将res1作为参数传给request2,并将request2的返回值赋值给res2
 var res3 = await request3(res2) //同理
 
 //这样子写的代码更加的美观,并且更符合我们平时编写代码的习惯
Salin selepas log masuk

【相关推荐:javascript视频教程编程视频

Atas ialah kandungan terperinci Adakah async merupakan atribut es6?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan