Promise ,async/await 基本用法

Promise ,async/await 基本用法

前言

异步代码的执行在JavaScript中总是以 callback(回调) 函数的执行来处理
但有多个异步执行等待的程序的时候,常见的结果可能是一个回调地狱
本文参考地址

代码结构看起来是这个样子的:
在这里插入图片描述
下图 图片来源:知乎,侵删

在这里插入图片描述


Promise 基本结构

Promise是一个对象

new Promise()

Promise的构造函数传入参数:一个函数

new Promise(()=>{
    
})

该函数接收的参数为,两个callback

resolve, 执行成功的回调

reject , 执行过程中任何一个失败,就会执行的回调

new Promise((resolve,reject )=>{
    
})

Promise 发起 ajax

这里不使用jQuery$.ajax, 因为jQueryajax,已经被封装了一次,返回了一个 Promise对象

使用原生的编程方式发送 ajax:

let p = new Promise((resolve,reject)=>{
		let xmlhttp = new XMLHttpRequest();
		xmlhttp.onreadystatechange =  () => {
			console.log(xmlhttp.readyState,xmlhttp.status)
			if (xmlhttp.readyState==4 && xmlhttp.status==200)
			{
				console.log("before call resolve")
				resolve( xmlhttp.responseText)  // 在完成响应后,且状态200 OK时,执行then
			}
			else if (xmlhttp.readyState==4 && xmlhttp.status!=200)
			{
				console.log("before call reject")
				reject(xmlhttp.responseText)  // 在完成响应后,状态异常时,执行catch
			}

		}
		xmlhttp.open("POST","http://192.168.15.16:8080/educloud/getHttpActionList",true);
		xmlhttp.send();

	}).then((data)=>{
		alert("success")
		console.log(data)
	}).catch((err)=>{
		alert("err")
		console.log(err)
	})

readyState 五个状态代表的意义

  • 0:未初始化,但是已经创建了XHR实例
  • 1:调用了open()函数
  • 2:已经调用了send()函数,但还未收到服务器回应
  • 3:正在接受服务器返回的数据
  • 4:完成响应

Promise 多个异步的情况下

Promise.all()

如果有两个 promise
难道就这么写?


let p1;
let p2;

p1.then(
    function(){
        p2.then()
    },
    function(){
        alert('failed')
    }
); 
// 岂不是看起来更辣鸡吗?

使用 Promise.all()

Promise.all();       // 承诺所有

Promise.all().then() //链式操作 点then()

Promise.all(
    [p1,p2] // all方法接收一个 数组作为参数,将你要异步操作的 承诺 p 放入其中
).then(
    function(){}, //所有的成功 resolve 才算 成功
    function(){}  //有一个失败 reject 就算 失败
);

all&&关系 都得成功才成功

Promise.race()

Promise.race() // 竞速 比如同时读五个资源,谁先来了 我用谁,谁先完成 我先运行谁

race||关系 有一个成功就行

async/await 修饰符

参考了大佬的博客

https://www.cnblogs.com/liquanjiang/p/11409792.html

async

async 是一个修饰符,async 定义的函数会默认的返回一个Promise对象resolve的值,因此对async函数可以直接进行then操作

async function fun1() {
    console.log(2)
    return 1
}

fun1().then( x => { console.log(x) })  

//  输出结果 2, 1,

也可返回一个新的Promise

async function fun2() {
    console.log('Promise1')
    return new Promise(function(resolve, reject){
        resolve('Promise2')
    })
}

fun2().then( x => { console.log(x) })   
// 输出
Promise1  
Promise2
Promise {<resolved>: undefined}

await

await也是一个修饰符,

await关键字只能放在标识了 async的函数的内部, await关键字的作用 就是获取 Promise中返回的内容, 获取的是Promise函数中resolve或者reject的值

vuexactions与后台的交互

async fillModuleConfig({commit}){	//vue store中 actions 提交 mutations
      await axios({
        method:'post',
        url:'http://192.168.15.16:8080/educloud/getHttpModuleList',

      }).then(function (response) {
        
        commit('setModuleConfig',response.data.list)

      })

    }

在组件中调用了fillModuleConfig()方法

this.fillModuleConfig().then(()=>{  //这里的this 是组件实例本身,无实际意义
    // 成功时执行
}).catch(()=>{
    // 失败时执行
})

上面这段代码,是定义一个函数 fillModuleConfig,并且用async标识该函数是一个异步执行的函数

在函数执行体中,使用了 axios的封装来发送 ajax, axios 已经实现了一套 Promise,所以可以使用.then()方法

然后使用 await标识 等待ajax代码执行完毕

最后在ajax代码执行完毕后,再执行一次 resolve或者是reject的逻辑 (调用函数的地方)

以同步代码的编写方式,写出异步代码的逻辑

const asy = function(x, time) {
    return new Promise((resolve, reject) =>{
        setTimeout(()=>{
            resolve(x)
        }, time)
    })
}

const add = async function() {
    const a = await asy(3, 5000)
    console.log(a)
    const b = await asy(4, 10000)
    console.log(b)
    const c =  await asy(5, 15000)
    console.log(c)
    
    console.log(a,b,c)
    const d = a + b +c  
    console.log(d)
}

add();

5秒后输出 :
3

10秒后输出:
4

15秒后输出:

5

345

12

如果await后面并不是一个Promise的返回值,则会按照同步执行处理

看到这里,代码就演变成了:
.
在这里插入图片描述

如果需要在等待执行n个异步操作后,再执行最后一个方法,那么最开始的 Promise发起 ajax的方法我们可以改写:

function todoGetData() {
	return new Promise((resolve,reject)=>{
	let xmlhttp = new XMLHttpRequest();
	xmlhttp.onreadystatechange =  () => {
		if (xmlhttp.readyState==4 && xmlhttp.status==200)
		{
			console.log("before call resolve")
			console.log(xmlhttp.responseText)
			resolve("ok")
		}
		else if (xmlhttp.readyState==4 && xmlhttp.status!=200)
		{
			console.log("before call reject")
			reject("error")
		}
	
	}
	xmlhttp.open("POST","http://192.168.15.16:8080/educloud/getHttpActionList",true);
	xmlhttp.send();
	})
}

async function func() {
	await todoGetData().then((data)=>{
		console.log(data)
	})
    //... 还可以写更多的异步代码配合 await使用
	console.log("all done")
}

func()

在成功的情况下依次输出:

before call resolve

xmlhttp.responseText中的数据

ok

all done

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值