ES6异步编程(promise到async的诞生)

我们知道js是有同步和异步任务的,这里简单的介绍以下它们的概念:
同步:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。
异步:不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
可以这么说,在目前最简单的异步任务就是定时器了。

好了,切入主题,今天主要讲到关于异步回调函数的成为同步处理及优化的过程;
在最初我们处理回调函数时,就是下面的处理:

var sayhello = function (name, callback) {
  setTimeout(function () {
    console.log(name);
    callback();
  }, 1000);
}
sayhello("我是第一个", function () {
  sayhello("我是第二个", function () {
    sayhello("我是第三个", function () {
      console.log("我是最后一个");
    });
  });
});
//输出: 我是第一个 我是第二个 我是第三个 我是最后一个

这样在我们回调函数过多的情况下,会一层层嵌套,这样的代码着实让人头大,我们可以叫它回调地狱

那既然提出了问题,就得解决问题啊,于是这时一代救世主出现:Promise

简单介绍:Promise是一个构造函数,其原型上有then、catch方法,对象上有reject、resolve方法。通过new关键字创建Promise对象

  • resolve:异步操作执行成功后的回调函数
  • reject:异步操作执行失败后的回调函数
//链式实现同步依次执行
function runAsync1() {
     return new Promise((resolve, reject) => {
         setTimeout(() => {
             console.log("我是第一个吗?");
             resolve("我要成为第一");
         }, 5000)
     })
 }
 function runAsync2() {
     return new Promise((resolve, reject) => {
         setTimeout(() => {
             console.log("我是第二个吗?");
             resolve("我要成为第二");
         }, 2000)
     })
 }
 function runAsync3() {
     return new Promise((resolve, reject) => {
         setTimeout(() => {
             console.log("我是最后一个吗?");
             resolve("我成为了最后");
         }, 0)
     })
 }
 runAsync1().then(data1 => {
     console.log(data1);
     return runAsync2();
 }).then(data2 => {
     console.log(data2);
     return runAsync3();
 }).then(data3 => {
     console.log(data3);
 });

在这里插入图片描述

它可以通过链式编程,即使你有再多的回调函数,我都可以通过then来获取执行同时达到了同步执行任务的目的。

但是,这样看着还是有点别扭,这么多链子,而且每一次都要返回一个回调函数以获取下一个回调函数任务,略显繁琐,于是第二代救世主诞生:async

async(异步函数):它既解决了异步编程回调地狱问题,又不会显得繁琐。
简单介绍:

  • 在普通函数定义前面加上async关键字,普通函数变为了异步函数;
  • 异步函数默认的返回值是一个promise对象(不是undefined);
  • 可以使用throw关键字将错误抛出。
//函数加了async,返回值会默认封装成promise对象
//无论是基本数据类型 还是引用型数据类型都是自动会封装成promise对象
async function test1() {
    return { name: "小王" }
}
async function test2() {
    return function () { console.log(11); }
}
async function test3() {
    return [1];
}
async function test4() {
    return 123;
}
console.log(test1()); //Promise {<fulfilled>: {…}}
console.log(test2()); //Promise {<fulfilled>: ƒ}
console.log(test3()); //Promise {<fulfilled>: Array(1)}
console.log(test4()); //Promise {<fulfilled>: 123}

从上验证返回的是一个promise对象。

await:async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值

await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用。如果在 async function 函数体外使用 await ,你只会得到一个语法错误。

async function test() {
	throw "呀,发生错误!!!";
}
test().catch(error => console.log(error)); //"呀,发生错误!!!"

我们看看它是如何进行优化回调问题的。

//async 函数诞生,优化了promise的繁琐链式调用
function runAsync1() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("我是第一个吗?");
            resolve("我要成为第一");
            // reject("发生错误!!!")
        }, 5000)
    })
}
function runAsync2() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("我是第二个吗?");
            resolve("我要成为第二");
        }, 2000)
    })
}
function runAsync3() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("我是最后一个吗?");
            resolve("我成为了最后");
        }, 0)
    })
}
//对比前面,没有繁琐的then链式,更加简单轻便了
async function getRes() {
    let res1 = await runAsync1();
    console.log(res1);
    let res2 = await runAsync2();
    console.log(res2);
    let res3 = await runAsync3();
    console.log(res3);
}
getRes();

在这里插入图片描述

从结果上看,我们获得了像promise一样的结果,但它大大减少了我们的代码量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值