async/await的用法

本文深入探讨ES6中Promise的静态方法.all及async/await的使用,讲解如何用async/await优化Promise,实现更简洁的异步代码编写。通过实际案例,展示在Vue等框架中如何优雅地管理接口请求。

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

es6 promise 静态方法+.all等待其他函数执行完再执行_心动止于人海。的博客-CSDN博客

https://segmentfault.com/a/1190000015488033

https://segmentfault.com/a/1190000019006291?utm_source=tag-newest

函数回调 

async created() {
    this.companyDescList = await this.getCityOptions();
  },

//城市换接口
    getCityOptions() {
      return new Promise((resolve, reject) => {
        let params = {
          haveProv: 1, // 包含全省
        };
        this.$http({
          url: this.$http.adornUrl(
            "/assessment/tassexcanncumulative/getCityOptions"
          ),
          method: "get",
          params: this.$http.adornParams(params),
        }).then(({ data }) => {
          if (data && data.code == 0) {
            let arr = data.list || [];
            resolve(arr);
          } else {
            reject([]);
          }
        });
      });
    },

return this.$http({
        url: this.$http.adornUrl("/indicator/factors/getListAll"),
        method: "get",
        params: this.$http.adornParams({
          yearMonth: time,
          cityName: city ? city : "",
          indicatorName: indicator ? indicator : "",
          lineName: line ? line : "",
          userDeptName: dept ? dept : "",
        }),
      })


this.$refs.super1
            .getDataList(
              this.dataForm.yearMonth,
              cityName,
              indicator,
              lineType,
              department
            )
            .then((res) => {
              console.log(res, "aaaaaa");
            });

介绍:

同步代码编写方式: Promise使用then函数进行链式调用,一直点点点,是一种从左向右的横向写法;async/await从上到下,顺序执行,就像写同步代码一样,更符合代码编写习惯;

多个参数传递: Promise的then函数只能传递一个参数,虽然可以通过包装成对象来传递多个参数,但是会导致传递冗余信息,频繁的解析又重新组合参数,比较麻烦;async/await没有这个限制,可以当做普通的局部变量来处理,用let或者const定义的块级变量想怎么用就怎么用,想定义几个就定义几个,完全没有限制,也没有冗余工作;

同步代码和异步代码可以一起编写: 使用Promise的时候最好将同步代码和异步代码放在不同的then节点中,这样结构更加清晰;async/await整个书写习惯都是同步的,不需要纠结同步和异步的区别,当然,异步过程需要包装成一个Promise对象放在await关键字后面;

async/await是对Promise的优化: async/await是基于Promise的,是进一步的一种优化,不过在写代码时,Promise本身的API出现得很少,很接近同步代码的写法;

async函数返回类型为Promise对象: 这是和普通函数本质上不同的地方,也是使用时重点注意的地方;
(1)return newPromise();这个符合async函数本意;
(2)return data;这个是同步函数的写法,这里是要特别注意的,这个时候,其实就相当于Promise.resolve(data);还是一个Promise对象,但是在调用async函数的地方通过简单的=是拿不到这个data的,因为返回值是一个Promise对象,所以需要用.then(data => { })函数才可以拿到这个data;
(3)如果没有返回值,相当于返回了Promise.resolve(undefined);

  • 如果async函数中是return一个值这个值就是Promise对象中resolve的值
  • 如果async函数中是throw一个值这个值就是Promise对象中reject的值
async function imAsync(num) {
  if (num > 0) {
    return num // 这里相当于resolve(num)
  } else {
    throw num // 这里相当于reject(num)
  }
}

imAsync(1).then(function (v) {
  console.log(v); // 1
});

// 注意这里是catch
imAsync(0).catch(function (v) {
  console.log(v); // 0
})

4)无等待 联想到Promise的特点,在没有await的情况下执行async函数,它会立即执行,返回一个Promise对象,并且绝对不会阻塞后面的语句,这和普通返回Promise对象的函数并无二致;

5)await不处理异步error: await是不管异步过程的reject(error)消息的,async函数返回的这个Promise对象的catch函数负责统一抓取内部所有异步过程的错误;async函数内部只要有一个异步过程发生错误,整个执行过程就中断,这个返回的Promise对象的catch就能抓取到这个错误;

5)async函数的执行: async函数执行和普通函数一样,函数名带个()就可以了,参数个数随意,没有限制,也需要有async关键字;只是返回值是一个Promise对象,可以用then函数得到返回值,用catch抓整个流程中发生的错误;

await关键字

1)await只能在async函数内部使用:不能放在普通函数里面,否则会报错;

2)await关键字后面跟Promise对象:在Pending状态时,相应的协程会交出控制权,进入等待状态,这是协程的本质;不加 return

3)await是async wait的意思: wait的是resolve(data)的消息,并把数据data返回,比如下面代码中,当Promise对象由Pending变为Resolved的时候,变量a就等于data,然后再顺序执行下面的语句console.log(a),这真的是等待,真的是顺序执行,表现和同步代码几乎一模一样;

async function testSync() {
   const datas= await new Promise((resolved, rejected) => {
       setTimeout(() => {
           resolved("async await test...");
         }, 1000);
    });
      console.log(datas);
 }
 
testSync();//async await test...


// async/await方式调用
function sayHi(name) {
  return new Promise((resolved, rejected) => {
    setTimeout(() => {
      resolved(name);
    }, 2000)
  })
}

//async function 声明用于定义一个返回 AsyncFunction 对象的异步函数。
异步函数是指通过事件循环异步执行的函数,它会通过一个隐式的 Promise 返回其结果。

async function sayHi_async(name) {
  const sayHi_1 = await sayHi(name)
  console.log(`你好, ${sayHi_1}`)
  const sayHi_2 = await sayHi('李四')
  console.log(`你好, ${sayHi_2}`)
  const sayHi_3 = await sayHi('王二麻子')
  console.log(`你好, ${sayHi_3}`)
}

sayHi_async('张三')
// 你好, 张三
// 你好, 李四
// 你好, 王二麻子

vue:
import Api from "../../utils/http";

async search() {
      // api调用
      let datas=await Api.get(
        "/refer",
        {
          name: this.searchValue
        },
        null
      );
      this.$store.state.common.searchValue = this.searchValue;
    },

Vuex结合 async/await 优雅的管理接口请求

async 函数返回一个 Promise 对象

async 函数内部 return 返回的值。会成为 then 方法回调函数的参数。

async function  f() {
    return 'hello world'
};
f().then( (v) => console.log(v)) // hello world

async setMapOption () {
      await this.$http({
        url: this.$http.adornUrl(this.apiName + '/bgtPlanTotal'),
        method: 'post',
        params: this.$http.adornParams({
          'yearMonth': this.filterMonth
        })
      }).then(({ data }) => {
      })
}

//添加任务
    async TaskList({ commit, state }, param) { //commit 直接调用mutation里面的方法
        let res = await TaskList(param);
        console.log(res.data, '任务列表')
        commit('TaskList', res.data.Result)
        return res.data.Result;//返回值相当于Promise对象中resolve的值
    },


// try/catch的实现
async function updateUserInfo (userId) {
    try {
        const res = await fetchUser(userId);
        if (res.ok) {
            doSuccessAction(res.json());
        } else {
            doWarnAction(res.json());
        }
    } catch (error) {
        if (error instanceof TypeError) {
           toast.show("Network Error");
           console.error("fetch operation error: ", error.message);
        }
    }
}

用async/ await来发送异步请求,从服务端获取数据,等待获取数据,然后处理数据。

vue中用async/await 来处理异步 - 简书 用async/await处理异步回调

methods: {

/////////////////页面可以用then回调 actions.js里面加return  Vuex
//添加任务
    async TaskList({ commit, state }, param) { //commit 直接调用mutation里面的方法
        let res = await TaskList(param);
        console.log(res.data, '任务列表')
        commit('TaskList', res.data.Result)
        return res.data.Result;
    },

//页面就可以用回调获取数据(Vue页面)
//任务列表 GetTaskList //mapActions 函数  TaskList //mapState 初始数据
    this.GetTaskList({
       Page: this.currentPage,
      Total: this.pageSize,
      SearchTxt: "" 
    }).then(data =>{ //成功后回调
      this.total = data[0].Allcount;
      console.log(data,'回调 data=this.TaskList');
      console.log(this.TaskList,'this.TaskList')
    })
//////////
//GetTaskList actions 函数
async generateData() { //另写一个函数
      let datas = await this.GetTaskList({
       Page: this.currentPage, //页码
      Total: this.pageSize, //显示条数
      SearchTxt: "" //搜索条件(可选填)
    })
      console.log(datas,'datas');
      // this.datalist = _result.data;
},

async generateData() {
      let datas = await this.$store.dispatch("UpgradeTaskmanage/TaskList", {
        Page: this.currentPage, //页码
        Total: this.pageSize, //显示条数
        SearchTxt: "" //搜索条件(可选填)
      });
      console.log(datas,'datas');
      // this.datalist = _result.data;
    },
// 等待getProductslist() 方法执行后返回数据给_result,然后再对返回的数据做更多的操作。

回调:
      async getNumber() {
     // 在 actions 函数里 await 也行 看具体需求   此例只作为演示 await 调用
        const datas = await this.$store.dispatch(`${moduleName}/getContractNumber`)
        this.contractInfo.fileNo = datas.fileNo
      },

async login() {
//         let loginInfo = await this.http.post('/api/login/doLogin', this.loginInfo)
//         // 提交mutation 保存token
//         this.$store.commit('updateToken', token)
//         setTimeout(() => {
//             this.$router.push('/')
//         }, 300)
//     }
// }

// 获取数据字典
async function getInitData({commit, state}, params) {
 const num = await getContractNumber()
  return new Promise((resolve, reject) => {
    axios.get(INTERFACE.GET_INIT_DATA).then((data) => {
    commit('SET_INIT_DATA', {data})   // 改变state.initData
      resolve(data.data)
    }).catch((err) => {
      window.Alert(err)  // 全局错误提示
    })
  })
}

async 函数返回的 Promise 对象,必须等到内部所有的 await 命令的 Promise 对象执行完,才会发生状态改变

也就是说,只有当 async 函数内部的异步操作都执行完,才会执行 then 方法的回调。

const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
async function f(){
    await delay(1000);
    await delay(2000);
    await delay(3000);
    return 'done';
}
f().then(v => console.log(v)); // 等待6s后才输出 'done'

async function timeout() {
    return 'hello world'
}
timeout().then(result => {
    console.log(result);
})
console.log('虽然在后面,但是我先执行');

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值