2020-09-24---Promise & jsonP

52 篇文章 0 订阅

Promise

一、什么是promise?

是ES6提出的一种异步编程解决方案。它是一个构造函数Promise

二、语法:

//resolve : 成功    reject : 失败
    new Promise((resolve,reject)=>{
        //处理的异步程序
        if(处理成功){
            resolve();
        }else{
            reject();
        }
    });

三、方法

Promise.prototype.then : 当promise返回resolve状态时,可以调用then方法
Promise.prototype.catch : 当promise返回reject状态时,可以调用catch方法

四、Promise有三种状态

resolved : 成功
reject : 失败
pending : 进行中

五、 Promise的静态方法 Promise.all()

all : 当数组中所有返回的promise对象全部返回resolve状态时,当前all方法返回resolve.如果有一个promise对象返回reject,那么当前all方法返回reject.

当有多个异步程序时

new Promise((resolve,reject)=>{
    if(){
        resolve()
    }else{
        reject()
    }
}).then(()=>{
    return new Promies(){}
}).then(()=>{
    return new Promise(){}
}).catch(()=>{})

应用

1.计时器回调函数

要实现3秒后输出数字3,2秒后输出数字2,1秒后输出数字1的效果,应为计时器是异步函数,如果不嵌套就会同时进行,必须嵌套使用才能实现我们上面的效果。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>01计时器回调函数</title>
</head>
<body>
    <script>
        setTimeout(() => {
            alert(1);
            setTimeout(() => {
                alert(2);
                setTimeout(() => {
                    alert(3);
                },1000)
            },2000)
        },3000)
    </script>
</body>
</html>

但是层级的回调嵌套会造成回调地狱。所以有了Promise来解决这个问题

2.计时器Promise

下面这个只是使用了一个Promise

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>03计时器promise</title>
</head>
<body>
    <script>
        new Promise((resolve,reject) => {
           setTimeout(() => {
               resolve();
           },3000);
        }).then(() => {
            alert(3);
            setTimeout(() => {
                alert(2)
            },2000);
        })
    </script>
</body>
</html>

3.计时器 Promise

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>05计时器promise</title>
</head>
<body>
    <script>
        new Promise((resolve,reject) => {
            setTimeout(() => {
                resolve();
            },3000)
        }).then(() => {
            alert(3);
            return new Promise((resolve,reject) => {
                setTimeout(() => {
                    resolve();
                },2000)
            })
        }).then(() => {
            alert(2);
            setTimeout(() => {
                alert(1);
            },1000)
        })
    </script>
</body>
</html>

4.ajax & 回调嵌套

ajax.js

let ajax = {};
ajax.get = function (url,fnWin,fnFail) {
    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
    xhr.open('get',url,true);
    xhr.send();
    xhr.onreadystatechange = function () {
        if(xhr.readyState === 4){
            if(xhr.status === 200){
                if(fnWin instanceof Function){
                    fnWin(xhr.responseText);
                }
            }else{
                if(fnFail instanceof Function){
                    fnFail();
                }
            }
        }
    }
}
ajax.post = function (url,data,fnWin,fnFail) {
    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
    xhr.open('post',url,true);
    xhr.setRequestHeader('Content-type','Application/x-www-form-urlencoded;charset=utf-8');
    xhr.send(data);
    xhr.onreadystatechange = function () {
        if(xhr.readyState === 4){
            if(xhr.status === 200){
                if(fnWin instanceof Function){
                    fnWin(xhr.responseText);
                }
            }else{
                if(fnFail instanceof Function){
                    fnFail();
                }
            }
        }
    }
}


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>02ajax回调嵌套</title>
</head>
<body>
    <script src="js/ajax.js"></script>
    <script>
        ajax.get('02text1.txt',data => {
            ajax.get(data,data => {
                ajax.get(data,data => {
                    alert(data);
                })
            })
        })
    </script>
</body>
</html>

5.ajax & promise

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>04ajax promise</title>
</head>
<body>
    <script src="js/ajax.js"></script>
    <script>
        new Promise((resolve,reject) => {
            ajax.get('02text1.txt',data => {
                resolve(data);
            })
        }).then((data) => {
            ajax.get(data,data => {
                alert(data);
            })
        })
    </script>
</body>
</html>

6.ajax & promise

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>06ajax promise</title>
</head>
<body>
    <script src="js/ajax.js"></script>
    <script>
        new Promise((resolve,reject) => {
            ajax.get('02text1.txt',(data) => {
                resolve(data);
            })
        }).then((data) => {
            return new Promise((resolve,reject) => {
                ajax.get(data,data => {
                    resolve(data);
                })
            })
        }).then(data => {
            ajax.get(data,data => {
                alert(data);
            })
        })
    </script>
</body>
</html>

Ajax的同源策略

同源是指:同协议,同域名(主机名)和同端口。
当要访问不同域名,或者不同协议,或者不同端口的时候需要跨域访问。

跨域方式有

  1. 后端代理
  2. jsonP
  3. xhr2
  4. Nginx

jsonP(前端可以实现的跨域方式)

jsonP原理:
本质是利用了src跨域的特点。通过动态创建script标签,设置src属性为对方的接口地址,以get方式传递请求,并将响应的结果通过回调函数返回。
要主注意:回调函数必须是全局函数

使用jsonP实现淘宝的搜索下拉提示

思路:当我们在搜索框输入我们想要搜索的内容,键盘弹起的那一刻,下面出来一系列和我们搜索相关的提示,即键盘弹起事件。
当键盘弹起的时候,动态地创建一个script标签,并设置它的src属性值为我们提前在淘宝找好的接口地址,然后修改接口地址里面的两个地方,第一个是把关键字修改为当前文本输入框的值,第二个是回调函数的名字,修改为我们自己写的回调函数的名字。

例如,当我们在淘宝的输入框输入 hua ,然后我们在控制台找见一个接口地址为 https://suggest.taobao.com/sug?code=utf-8&q=hua&_ksTS=1600949240906_450&callback=jsonp451&k=1&area=c2c&bucketid=4 然后在里面找我们在输入框输入对的 hua,把这个值改为this.value,即我们在输入框输入的值;然后在接口地址中找见回调函数,一般为cb或者callback,把这个值修改为我们自己写的回调函数的名字。修改之后为:https://suggest.taobao.com/sug?code=utf-8&q=${this.value}&_ksTS=1600949240906_450&callback=fn&k=1&area=c2c&bucketid=4

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jsonP</title>
    <style>
        input{
            width: 300px;
            height: 30px;
            border: 2px solid orange;
            border-radius: 15px;
            outline: none;//去掉input控件的外边框
        }
        a{
            text-decoration: none;
            color: black;
            font-weight: 900;
            display: inline-block;
            margin-bottom: 10px;
        }
        #box{
            width: 305px;
            height: 350px;
            border: 2px solid gray;
            /* display: none; */
        }
    </style>
</head>
<body>
    <input type="text" name="" id="">
    <div id="box"></div>
    <script>
        //jsonP前端跨域的方法,动态地创建script标签,利用其scr属性的跨域特点,设置src属性为对方的接口地址,一get方式传递请求,并将响应结果通过回调函数返回。要注意,回调函数必须是全局函数
        
        //百度
        // https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=32617,1464,32328,31253,32723,7632,32115,32719,26350&wd=yi&req=2&csor=2&pwd=y&cb=jQuery1102009665188345799813_1600947605277&_=1600947605280

        //淘宝
        // https://suggest.taobao.com/sug?code=utf-8&q=hua&_ksTS=1600949240906_450&callback=jsonp451&k=1&area=c2c&bucketid=4

        let o_box = document.querySelector('div');
        let o_txt = document.querySelector('input');
        // o_txt.onfocus = 
        o_txt.onkeyup = function(){
            //每次按下都清空一下页面的内容
            o_box.innerHTML = '';
            //动态创建script
            let o_scr = document.createElement('script');
            // o_scr.src = `https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=32617,1464,32328,31253,32723,7632,32115,32719,26350&wd=${this.value}&req=2&csor=2&pwd=y&cb=fn&_=1600947605280`;
            o_scr.src = `https://suggest.taobao.com/sug?code=utf-8&q=${this.value}&_ksTS=1600949240906_450&callback=fn&k=1&area=c2c&bucketid=4`;
            //把scrip标签放到head中
            document.head.appendChild(o_scr);
        }
        function fn(data){
            //回调函数带回来的数据打印一下,判断是什么类型的数据,然后确定要怎么获取

            //百度  把获取到的内容输入在ul li 中
            // console.log(data);  //对象
            //然后逐层找我们想要的数据
            // console.log(data.g);  //数组
            //遍历数组  
            // data.g.forEach((value) => {
            //     // console.log(value.q);  //我们想要的数据
            //     //创建li
            //     let o_li = document.createElement('li');
            //     o_li.innerHTML = '<a href="http://1000phone.com">' + value.q + '</a>';
            //     o_ul.appendChild(o_li);
            // })
            

            //淘宝
            // console.log(data);  //对象
            //然后逐层找我们想要的数据
            // console.log(data.result);  //数组
            //遍历数组  
            data.result.forEach((value) => {
                // console.log(value[0]);  //我们想要的数据
                o_box.innerHTML += '<a href="http://1000phone.com">' + value[0] + '</a>' + '<br>';
                // o_box.appendChild();
            })
        }
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值