Promise异步async&await


在这里插入图片描述
JavaScript是单线程的,在代码的执行过程中,碰见异步代码,先单独放置另一队列,原有队列继续执行(不被阻塞)。

引入

如果我们需要依次的执行多个异步操作,我们的代码可能就要写成这样,这个我们就叫作 回调地狱(Callback Hell)。
Promise就是为了解决这个问题。

// 异步操作进行层层嵌套,使得依次执行
        setTimeout(() => {
            console.log("异步1要做的事情");
            setTimeout(() => {
                console.log("异步2要做的事情");
                setTimeout(() => {
                    console.log("异步3要做的事情");
                },2000)
            },1000)
        },3000)
        console.log("虽然我在后面,但是我不会等前面的异步操作");
        console.log("666");
        console.log("你说呢");
// 程序会依次执行 异步1 -> 异步2 -> 异步3
// 3s -> 1s -> 2s

执行结果:
在这里插入图片描述

Promise

为什么出现 Promise
遇到一个请求要依赖前一个请求的结果,如果多个层层回调函数的嵌套叫做“回调地域”,代码不美观而且不易于维护。
Promise的优点在于可以用链式结构将多个异步操作串联起来
Promise 对象有三个状态:pending、fulfilled 和 rejected。
resolve :在异步操作成功时调用,将异步操作的结果,作为参数传递出去,并使Promise状态变为fulfilled。
reject :在异步操作失败时调用,将异步操作报的错误,作为参数传递出去,并使Promise状态变为 rejected。

// 链式调用, 顺序执行异步
        axios.get(url)
        .then()
        .then()
        .catch()
        .finally();
        const promise = new Promise((resolve,reject) => {
            // 这里做异步任务 axios 等 暂且用 setTimeout 模拟
            //------------- 
            setTimeout(function(){
                let data = {retCode:0,msg:'jkl'};
                if(data.retCode == 0){
                    // 异步操作成功
                    resolve(data);									// pending -> fullfilled
                    console.log("成功执行");
                }else{
                    // 异步操作失败
                    reject({retCode:-1,msg:'netWork error'});		// pending -> rejected
                    console.log("执行失败");
                }
            },1000);
            //-------------
            console.log("fewfewgwegweg");
        });

在这里插入图片描述
这个Promise对象是会立即执行的。
then方法和catch方法都是异步代码
当Promise对象中是resolve时,外面可以没有then去处理。
当Promise对象中是reject时,外面要么then要写第二个函数参数去处理,要么使用链式catch的方式去处理,反正必须要处理。

async&await

async关键字,是声明异步函数,返回值是promise对象,如果返回的不是promise,会自动用Promise.resolve()包装。
await 后 是一个 Promise对象。

        const fun1 = function(){
            return new Promise((resolve,reject) => {
                // 异步操作 1
                resolve("data1....")
            });
        };
        const fun2 = function(){
            return new Promise((resolve,reject) => {
                // 异步操作 2
                resolve("data2....")
            });
        };

        const asyncFun = async function(){
            let res1 = await fun1();
            let res2 = await fun2();
            
            console.log("hello"); 
            console.log(res1);				// data1....
            console.log(res2);				// data2....
        }
        asyncFun();
        console.log("sffsdgd");  

在这里插入图片描述
await等后面的promise对象执行完毕,然后拿到resolve()的值并进行返回,之后继续向下执行。
如果 Promise中没有 resolve,就会引起 asyncFun 函数内部执行的阻塞,await一直在等待,只打印 sffsdgd
但是对于 asyncFun 函数 外部的代码来说没有影响。

Attention:
await 命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try…catch 代码块中。

async function myFunction() {
  try {
    await somethingThatReturnsAPromise();
  } catch (err) {
    console.log(err);
  }
}

JS异步顺序调用
await用法
Promise
Promise详解

Promise处理多次 Ajax 请求

        function queryData(url) {
            return new Promise((resolve, reject) => {
                let xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function() {
                    if (xhr.readyState != 4) return;
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        // 处理正常情况
                        // xhr.responseText 是从接口拿到的数据
                        resolve(xhr.responseText); 
                    } else {
                        // 处理异常情况
                        reject('接口请求失败');
                    }
                };
                xhr.responseType = 'json'; // 设置返回的数据类型
                xhr.open('get', url);
                xhr.send(null); // 请求接口
            });
        }
        // 发送多个ajax请求并且保证顺序
        queryData('http://localhost:3000/api1')
            .then(
                data1 => {
                    console.log(JSON.stringify(data1));
                    // 请求完接口1后,继续请求接口2
                    return queryData('http://localhost:3000/api2');
                }
            )
            .then(
                data2 => {
                    console.log(JSON.stringify(data2));
                    // 请求完接口2后,继续请求接口3
                    return queryData('http://localhost:3000/api3');
                }
            )
            .then(
                data3 => {
                    // 获取接口3返回的数据
                    console.log(JSON.stringify(data3));
                }
            );

then方法
return 后面的返回值,有两种情况:
情况1:返回 Promise 实例对象。返回的该实例对象会调用下一个 then。
情况2:返回普通值。返回的普通值会直接传递给下一个then,通过 then 参数中函数的参数接收该值。

       .then(data2 => {
            console.log(JSON.stringify(data2));
            // 返回普通值
            return 'qianguyihao';
        })
        /*
            这里会产生一个新的 默认的 promise实例,来调用这里的then,确保可以继续进行链式操作。
        */
        .then(data3 => {
            // 这里的 data3 接收的是 普通值 'qianguyihao'
            console.log(data3);
        });
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值