从Promise到异步函数(async,await)

从Promise到异步函数(async,await)

Promise

  • Promise出现的目的是解决js异步编程中回调地狱的问题。
  • Promise本身没有提供新的功能,它只是异步编程中语法上的改进。
  • Promise是一个构造函数,如果你需要使用Promise就需要new一个Promise实例对象。

语法示例

  • 接下来我们将用定时器代替来异步API演示。
let promise = new Promise((resolve, reject) => {
	setTimeout(() => {
		if (true){
			resolve('异步API的执行结果');
		}else{
			reject('异步API的失败执行结果');
		}
	}, 2000)
});
// promise允许链式调用
promise.then(result => console.log(result)) //异步API的执行结果
       .catch(error => console.log(error)); //异步API的失败执行结果
  • resolve(函数)
    • 将异步API的执行结果传递出去
  • reject(函数)
    • 将异步API的失败执行结果传递出去
  • then(方法)
    • 获取异步API的执行结果
  • catch(方法)
    • 获取异步API的失败执行结果

用Promise解决回调地狱

  • 出现了一个异步API的执行需要上一个异步API的执行结果的问题,我们用定时器来代替异步API演示
let a = 0;
setTimeout(() => {
	let b = a + 1;
	console.log(b);
	setTimeout(() => {
		let c = b + 1;
		console.log(c);
		setTimeout(() => {
			let d = c + 1;
			console.log(d);
		}, 2000)
	}, 2000)
}, 2000)

// 用Promise解决回调地狱,先用promise把每一个‘异步函数封装’
function p1() {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			let b = a + 1;
			resolve(b);
			reject('p1失败了');
		}, 2000)
	});
}
			
function p2(b) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			let c = b + 1;
			resolve(c);
			reject('p2失败了');
		}, 2000)
	});
}
			
function p3(c) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			let d = c + 1;
			resolve(d);
			reject('p3失败了');
		}, 2000)
	});
}
//然后再链式调用.then和.catch方法,并且将下一个需要调用的函数return回去,并且将参数传递	
p1().then((r1) => {console.log(r1); return p2(r1);}) //1
    .then((r2) => {console.log(r2); return p3(r2);}) //2
    .then((r3) => {console.log(r3);})				 //3
    .catch((err) => {console.log(err)});			 //当出现失败的情况时,使用catch()中断,并且失败结果会一层一层传到最下面的catch()

异步函数

  • 异步函数是异步编程语法的中终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,是代码变得更加清晰。

语法

  • 在普通函数定义的前面加上async关键字 普通函数就变成了异步函数
  • 异步函数默认的返回值是promise对象
  • 在异步函数内部使用return关键字进行结果返回,结果会被包裹在promise对象中,return关键字代替了resolve方法
  • 在异步函数内部使用throw关键字抛出程序异常
  • 调用异步函数在链式调用then()方法获取函数执行结果
  • 调用异步函数再链式调用catch()方法获取函数执行的错误信息
const fn = async() => {};
async function fn() {};
async function fn() {
	return '执行成功'; //resolve
	throw '执行失败';  //reject
}
fn().then((res) => {console.log(res)})   //执行成功
    .catch((err) => {console.log(err)}); //执行失败

用异步函数解决回调地狱

  • await关键字
    • 它只能出现在异步函数中
    • await后面要跟promise对象,写其它类型的API是不可以的
    • 它可以暂停异步函数的执行,等待promise对象返回结果再向下执行函数
                        let a = 0;	
			function p1() {
				return new Promise((resolve, reject) => {
					setTimeout(() => {
						let b = a + 1;
						resolve(b);
						reject('p1失败了');
					}, 2000)
				});
			}
						
			function p2(b) {
				return new Promise((resolve, reject) => {
					setTimeout(() => {
						let c = b + 1;
						resolve(c);
						reject('p2失败了');
					}, 2000)
				});
			}
						
			function p3(c) {
				return new Promise((resolve, reject) => {
					setTimeout(() => {
						let d = c + 1;
						resolve(d);
						reject('p3失败了');
					}, 2000)
				});
			}
			async function run() {
				try{
					let r1 = await p1()
					console.log(r1); //1
					let r2 = await p2(r1);
					console.log(r2); //2
					let r3 = await p3(r2);
					console.log(r3); //3
				}catch(e) {
					console.log(e);//捕获错误
				}
			}
			run();

promise对象的进一步处理

function p() {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('成功');
			reject('失败');
		}, 2000)
	});
}

// 模仿ajax进一步处理promise对象

function pp() {
      return p().then(res => {
            // 处理的代码 res
            return res;
            // return的值会作为Promise对象下一个then的回调函数的参数值
      })
}

// 或者

async function pp() {
      const res =  await p();
      // 处理 res
      return res;
}

async function run() {
      const res = await pp();
}

结尾

  • 在实际开发中如果有一个异步函数的执行需要另一个异步函数的执行结果,我们就可以将异步请求API封装成promise方法,然后在用async和await将起写成同步代码的样式,简化代码并且方便阅读。
posted @ 2020-08-10 16:23  懒惰ing  阅读(1701)  评论(0编辑  收藏  举报