前言
😎😎欢迎来到我的博客😎😎
📔博主是一名大学在读本科生,主要学习方向是前端😊。
🍭目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏🤩
🛠目前正在学习的是🔥 R e a c t 框 架 React框架 React框架🔥,中间夹杂了一些基础知识的回顾⌨️
🌈博客主页👉codeMak1r.的博客
➕关注👍点赞📂收藏
🕹坚持创作✏️,一起学习📖,码出未来👨🏻💻!
🌟async函数
async关键字用来标识一个函数,async关键字标识过的函数为async函数。
- 函数的返回值为promise对象
- promise对象的结果由async函数执行的返回值决定
- async函数与promise.then()方法返回值情况类似
| async函数返回值 | async函数内部 | 
|---|---|
| promise对象,对象的状态为成功,成功的值由async函数内部的返回值决定 | 一个非promise类型的返回值 | 
| promise对象,状态为成功,成功的值为undefined。 | 没有声明return | 
| promise对象,状态为成功,成功的值为123. | return 123; | 
| promise对象,状态由返回值中的promise对象状态决定 对象的值由返回值中的promise对象的值决定 | 一个promise类型的返回值 | 
| promise对象,状态为失败; 失败的值为‘error’。 | return Promise.reject(‘error’) | 
| promise对象,状态为失败,失败的值为‘Oh NO!’ | throw ‘Oh NO!’ | 
<body>
  <script>
    async function main() {
     
      return Promise.reject('error')
    }
    let result = main()
    console.log(result)
  </script>
</body>
打印台显示:
result是一个prmoise类型的对象,状态为失败,值为error。
<body>
  <script>
    async function main() {
     
      throw 'Oh NO!'
    }
    let result = main()
    console.log(result)
  </script>
</body>
打印台显示:
result是一个promise类型的对象,状态为失败,值为‘Oh NO!’。
🌟await表达式
- await右侧的表达式一般为promise对象,但也可以是其他的值;
- 如果表达式是promise对象,await返回的是promise成功的值;
- 如果表达式是其他值,直接将此值作为await的返回值。
注意⚠️:
- await必须写在async函数中,但async函数中可以没有await;
- 如果await 的promise失败了,就会抛出异常,需要通过try…catch捕获处理。
1、右侧为成功的promise
async function main() {
   
  let p = new Promise((resolve, reject) => {
   
    resolve('Ok')
  })
  let res = await p
  console.log(res)
}
main()
打印台显示:
res结果为:Ok。
2、右侧不是promise类型的值
async function main() {
   
  let p = new Promise((resolve, reject) => {
   
    resolve('Ok')
  })
  let res = await 123
  console.log(res)
}
main()
打印台显示:
res结果为:123。
3、右侧的promise是失败状态
async function main() {
   
  let p = new Promise((resolve, reject) => {
   
    reject('Error')
  })
  try {
   
    let res = await p
    } catch (error) {
   
      console.log(error)
    }
}
main()
打印台显示:
Error。
🌟async_await结合使用——fs读取文件
普通回调函数读取文件操作:
const fs = require('fs');
fs.readFile('./resource/1.txt', (err, data1) => {
   
  if (err) throw err;
  fs.readFile('./resource/2.txt', (err, data2) => {
   
    if (err) throw err;
    console.log(data1 + data2)
  })
})
我们可以看出,这一段代码运用了回调函数的嵌套,一旦读取的文件数量多的话就非常不利于阅读与维护。
于是可以使用promise异步编程解决方法:
const fs = require('fs');
// promise封装读取文件函数
const read = (path) => {
   
  return new Promise((resolve, reject) => {
   
    fs.readFile(path, (err, data) => {
   
      if (err) reject(err);
      resolve(data.toString())
    })
  })
}
// 使用promise.then()方法读取文件
read('./resource/1.txt').then(value => {
   
  console.log(value)
  return read('./resource/2.txt')
}).then(value => {
   
  console.log(value)
}).catch(reason => {
   
  console.warn(reason)
})
使用了promise之后,我们可以用then方法的链式调用,调用读取的文件并将读取结果打印出来。
但是依旧不够简洁,最终的解决方案是使用async_await结合:
const fs = require('fs');
// async与await方式实现
const util = require('util')
// util.promisify转为promise类型的函数
const mineReadFile = util.promisify(fs.readFile)
async function main() {
   
  try {
   
    // 读取文件内容
    let data1 = await mineReadFile('./resource/1.txt')
    let data2 = await mineReadFile('./resource/2.txt')
    // 其实这里await读取文件依旧是异步的,只不过看上去像同步
    console.log(data1 + data2)
  } catch (error) {
   
    console.log(error)
  }
}
main();
util.promisify()方法将API转为promise类型的函数
这里的两行await代码看上去是同步代码,其实其内部依旧是异步读取文件,只不过看上去像是同步的。
🌟async_await结合使用——发送ajax请求
promise.then.catch方法发送ajax请求:
<body>
  <button id="btn">点击发送ajax请求</button>
  <script>
    function sendAJAX(url) {
   
      return new Promise((resolve, reject) => {
   
        const xhr = new XMLHttpRequest()
        xhr.open('GET', url)
        xhr.send()
        xhr.onreadystatechange = function () {
   
          if (xhr.readyState === 4) {
   
            if (xhr.status >= 200 && xhr.status < 300) {
   
              resolve(xhr.response)
            } else {
   
              reject(xhr.status)
            }
          }
        }
      })
    }
    const btn = document.getElementById('btn')
		// promise.then.catch写法
    btn.addEventListener('click', function () {
   
      sendAJAX('http://127.0.0.1:8000/server')
        .then(value => {
   
          console.log(value)
        })
        .catch(reason => {
   
          console.log(reason)
        })
    })
  </script>
</body>
async_await写法发送ajax请求:
<body>
  <button id="btn">点击发送ajax请求</button>
  <script>
    function sendAJAX(url) {
   
      return new Promise((resolve, reject) => {
   
        const xhr = new XMLHttpRequest()
        xhr.open('GET', url)
        xhr.send()
        xhr.onreadystatechange = function () {
   
          if (xhr.readyState === 4) {
   
            if (xhr.status >= 200 && xhr.status < 300) {
   
              resolve(xhr.response)
            } else {
   
              reject(xhr.status)
            }
          }
        }
      })
    }
    const btn = document.getElementById('btn')
    // async_await写法
    btn.addEventListener('click', async function () {
   
      try {
   
        let result = await sendAJAX('http://127.0.0.1:8000/server')
        console.log(result)
      } catch (error) {
   
        console.log(error)
      }
    })
  </script>
</body>
接收ajax请求的服务器:
server.js
const express = require('express')
const app = express()
app.all('/server', (request, response) => {
   
  response.setHeader('Access-Control-Allow-Origin', '*')
  response.setHeader('Access-Control-Allow-Headers', '*')
  response.setHeader('Access-Control-Allow-Methods', '*')
  response.send('codeMak1r.')
})
app.listen(8000, () => {
   
  console.log('服务已经监听到8000端口...')
})
🎉🎉如果觉得博主的文章还不错的话
➕关注博主👍点赞文章📁收藏文章
✏️原创不易你的支持将会是我最大的动力💪
🧸感谢观看
转载:https://blog.csdn.net/Svik_zy/article/details/125443099
