【JS】Day27

学习内容

  • 异步问题
  • promise基本语法
  • promise应用
  • async_awite
  • 面试版-ajax

异步问题

//1. 如何让异步程序按顺序执行?
//2. 具有依赖调用的问题?
//需求:3秒后输出1,再过2秒输出2,再过1秒输出3,再过半秒输出4
setTimeout(() => {
    alert(1);
    setTimeout(() => {
        alert(2);
        setTimeout(() => {
            alert(3);
            setTimeout(() => {
                alert(4);
            }, 500);
        }, 1000);
    }, 2000);
}, 3000);

//
<script src="js/index.js" type="module"></script>
=>    //导入模块
    import {ajax} from '../utils/utils.js';

    // let result = await ajax({ url: '/test/first'});
    // console.log(result);

    ajax({url: '/test/first'})
    .then((data) => {
        console.log(data);
    })

promise基本语法

//什么是Promise?

//ES6提出的异步编程解决方案;
//承诺的意思,是一个专门用来解决异步 回调地狱 的问题;
//回调地狱,其实就是回调函数嵌套过多导致的。

//当代码成为这个结构以后,已经没有维护的可能了;
//所以我们要把代码写的更加的艺术一些。

//检测机构
//new Promise((resolve,reject) => {
//    //resolve: 成功  reject:失败
//    if(异步程序){
//        resolve([参数])
//    }else{
//        reject([参数]);
//    }
//})
//原型方法
//then(([参数]) => {}) : 如果promise对象返回resolve时,可以调用then进行后续的处理
//catch(([参数] => {})): 如果promise对象返回reject时,可以调用catch方法进行后续的处理

// 3秒后输出1,再过2秒输出2
new Promise((resolve,reject) =>{
    setTimeout(() => {
        //成功了
        resolve(1);
    }, 3000);
})
.then((data) => {
    alert(data); //1
    setTimeout(() => {
        alert(2);
    }, 2000);
})
.catch((err) => {
    alert('失败');
})

promise应用

//Promise的静态方法

//Promise.all() 将调用所有的promse对象,全部返回resolve时,该对象才返回resolve。如果有一个promise返回reject时,该对象返回reject。

//面试题: promise中有三种状态,哪三种状态?

//1. pending: 进行中状态;
//2. resolved / fulfilled: 成功状态;
//3. rejected: 失败状态。
/*
这个时候,我们的代码已经改观了很多了;
基本已经可以维护了;
但是对于一个程序员来说,这个样子是不够的;
我们还需要更加的简化代码;
所以我们就需要用到一个 es7 的语法了;
叫做 async / await。
*/

//
//需求:3秒后输出1,再过2秒输出2,再过1秒输出3,再过半秒输出4
//创建promise对象
new Promise((resolve,reject) => {
    setTimeout(() => {
        resolve(1);
    }, 3000);
})
.then((data) => {
    alert(data); //1
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve(2);
        }, 2000);
    })
})
.then((data) => {
    alert(data); //2
    return new Promise((resolve,reject) =>  {
        setTimeout(() => {
            resolve(3);
        }, 1000);
    })
})
.then((data) =>  {
    alert(data); //3
    setTimeout(() => {
        alert(4);
    }, 500);
})
.catch(() => {
    console.log('失败');
})

//
//封装一个promise的函数
function loadImg(src){
    //创建一个promise对象
    return new Promise((resolve,reject) => {
        //创建一个img标签
        let img = new Image(); //document.createElement('img')
        //设置img的src属性
        img.src = src;  //后面的src是形参,接收回来的是一个图片地址
        //给图片注册加载事件
        img.onload = function(){
            //调用resolve
            resolve(this); //this: img对象
        }
        //给图片注册失败事件
        img.onerror = function(){
            reject(new Error('图片加载失败'));
        }
    })
}
//准备一个数组,存放所有的图片
let arr_img = ['./img/1.webp','./img/2.webp','./img/3.webp'];

//调用加载函数
let o_p = loadImg(arr_img[1]);
o_p.then((img) => { //走到这一步,说明浏览器已经加载图片成功了
    document.body.appendChild(img);
})
o_p.catch((err) => {
    console.log(err);
})

//
//封装一个加载图片的函数
function loadImg(url){
    //返回一个promise对象
    return new Promise((resolve,reject) => {
        //创建一个img对象
        let img = new Image();
        //设置src属性
        img.src = url;
        //注册成功的事件
        img.onload = function(){
            resolve(img);
        }
        //注册失败的事件
        img.onerror = function(){
            reject(new Error('图片加载失败'));
        }
    })
}
//准备一个数组,存放图片
let arr_img = ['./img/1.webp','./img/2.webp','./img/3.webp'];
//调用加载图片的函数
//all : 所有、全部
// let o_p = Promise.all([loadImg(arr_img[0]),loadImg(arr_img[11]),loadImg(arr_img[2])]);

let o_p = Promise.race([loadImg(arr_img[0]),loadImg(arr_img[1]),loadImg(arr_img[2])]);

o_p.then((img) => {
    document.body.appendChild(img);
})

// o_p.then((imgs) => {
//     let body = document.body;
//     imgs.forEach((item) => {
//         body.appendChild(item);
//     })
// })
// o_p.catch((err) => {
//     console.log(err);
// });

async_awite

//ASYNC / AWAIT

async / await 是一个 es7 的语法;
这个语法是 回调地狱的终极解决方案。
语法:
    async function fn() {
      const res = await promise对象
    }

//async 和 await 关键字

//注意: 需要配合的必须是 Promise 对象;
//注意: Promise 语法的调用方案;
//意义: 可以把异步代码写的看起来像同步代码。

//async 关键字的用法

//直接书写在函数的前面,表示该函数是一个异步函数;
//意义: 表示在该函数内可以使用 await 关键字。

//await 关键字的用法

//必须书写在一个有 async 关键字的函数内;
//await 后面等待的内容必须是一个 promise 对象;
//本该使用then接收的结果,可以直接定义变量接收。

//缺点

1. await 只能捕获到 promise 成功的状态;
2. 如果失败,会报错,终止程序继续执行。

//解决方案

//1. 使用 try catch 语法
  //语法: try { 执行代码 } catch(err) { 执行代码 };
  //首先执行 try 里面的代码, 如果不报错, catch 的代码不执行了;
  //如果报错, 不会爆出错误, 不会终止程序执行, 而是执行 catch 的代码, 把错误信息给到 err 参数。
//2. 改变封装 Promise 的思路
  //让当前的 Promise 对象百分百成功,让成功和失败都按照 resolve 的形式来执行,只不过传递出去的参数, 记录一个表示成功或者失败的信息。

//封装一个加载图片的函数
function loadImg(url){
    //返回一个promise对象
    return new Promise((resolve,reject) => {
        //创建一个img对象
        let img = new Image();
        //设置src属性
        img.src = url;
        //注册成功的事件
        img.onload = function(){
            resolve(img);
        }
        //注册失败的事件
        img.onerror = function(){
            resolve(new Error('图片加载失败'));
        }
    })
}
//准备一个数组,存放图片
let arr_img = ['./img/1.webp','./img/2.webp','./img/3.webp'];

async function fn(){  //处理异步程序
    //await : 将异步转为同步执行
    let img = await loadImg(arr_img[10]); //异步程序,返回一个promise对象.
    if(img instanceof Error){
        console.log(img);
    }else{
        document.body.appendChild(img); //添加到页面中
    }
}
fn();

面试版-ajax

<script>
    //面试题 :使用promise封装ajax
    let ajax = {
        get(url){  //url   fnWin  fnFaild
            //返回一个promise对象
            return new Promise((resolve,reject) => {
                //1. 创建xhr对象
                let xhr = new XMLHttpRequest();
                //2. 与服务器建立连接
                xhr.open('get',url,true);
                //3. 注册事件
                xhr.onreadystatechange = function(){
                    if(xhr.readyState === 4){
                        if(/^(2|3)\d{2}$/.test(xhr.status)){
                            //调用resolve
                            resolve(xhr.responseText);
                        }else{
                            //调用reject
                            reject();
                        }
                    }
                }
                //4. 发送请求
                xhr.send();
            })
        },
        post(url,data){
            return new Promise((resolve,reject) => {
                //1. 创建xhr对象
                let xhr = new XMLHttpRequest();
                //2. 与服务器建立连接
                xhr.open('post',url,true);
                //3. 注册事件
                xhr.onreadystatechange = function(){
                    if(xhr.readyState === 4){
                        if(/^(2|3)\d{2}$/.test(xhr.status)){
                            //调用resolve
                            resolve(xhr.responseText);
                        }else{
                            //调用reject
                            reject();
                        }
                    }
                }
                //4. 发送请求
                xhr.setRequestHeader('Content-type','Application/x-www-form-urlencoded');
                xhr.send(data);
            })
        }
    }
</script>
<script>
    ajax.get('http://localhost:8888/test/first')
    .then((data) => {
        console.log(data);
    })
    .catch(() => {
        console.log('请求失败');
    })

    ajax.get('http://localhost:8888/test/second')
    .then((data) => {
        console.log(JSON.parse(data));
    })
    .catch(() => {
        console.log('请求失败');
    })

    ajax.get('http://localhost:8888/test/third?name=张三&age=18')
    .then((data) => {
        console.log(JSON.parse(data));
    })
    .catch(() => {
        console.log('请求失败');
    })

    ajax.post('http://localhost:8888/test/fourth','name=张三&age=18')
    .then((data) => {
        console.log(JSON.parse(data));
    })
    .catch(() => {
        console.log('请求失败');
    })
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值