Promise对象

1、promise概念

* Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。

* 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

* 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

2、promise特点

有且只有这两种,而且一个peomise对象只能改变一次,无论变为成功还是失败,都会有一个结果数据,成功的结果数据一般为value,失败的结果数据一般被称为reason

它只有两种状态(PromiseState)可以转化,即

- **操作成功:**pending -> fulfilled/resolved

- **操作失败:**pending -> rejected

实例对象的值:PromiseResult。该对象保存的结果为异步任务成功和失败的结果

* 成功的结果 resolve 

* 失败的结果 rejected

promise有三个状态:

1、pending[待定]初始状态

2、fulfilled[实现]操作成功

3、rejected[被否决]操作失败

resolve作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

3、promise实现原理

ES6 规定,`Promise` 对象是一个构造函数,用来生成 `Promise` 实例。通过在函数内部 return 一个 `Promise` 对象的实例,这样就可以使用 `Promise` 的属性和方法进行下一步操作了。

```javascript

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署

promise的方法:`then()`方法就是把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数.

而 `Promise`的优势就在于这个链式调用。我们可以在 then 方法中继续写 `Promise` 对象并返回,然后继续调用 `then` 来进行回调操作。

问题一:函数内部的异步函数

怎样才能取得到函数内部的data

```

```javascript

1、promise构造函数的参数是个函数

2、该函数的参数有两个:resolve,reject

  resolve:异步操作成功,要调用的函数。是then函数的第一个参数

  reject表示操作失败,要调用的时候是then函数的第二个参数

```4、promise的api方法

4.1、**.then(callback)**

Promise对象含有then方法,then()调用后返回一个Promise对象,意味着实例化后的Promise对象可以进行链式调用,而且这个then()方法可以接收两个函数,一个是处理成功后的函数,一个是处理错误结果的函数。

var promise1 = new Promise(function(resolve, reject) {

  // 2秒后置为接收状态

  setTimeout(function() {

    resolve('success');

  }, 2000);

});

promise1.then(function(data) {

  console.log(data); success

}, function(err) {

  console.log(err); // 不执行

}).then(function(data) {

  // 上一步的then()方法没有返回值

  console.log('链式调用:' + data); // 链式调用:undefined 

}).then(function(data) {

  // ....

});

4.2、**.catch(callback)**

catch()方法和then()方法一样,都会返回一个新的Promise对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略then()方法的第二个参数,把错误处理控制权转交给其后面的catch()函数

```javascript

const p = new Promise((resolve, reject) => {

            //  修改p的状态

    reject('失败')

})

console.log(p);

p.catch(data => {

    console.log(data);

})

4.3、**.all()**

Promise.all()  

Promise包含n个promise的数组,说明:返回一个新的promise,只有promise都成功才成功,只要有一个失败了,就都失败

```javascript

 const p1 = new Promise((resolve, reject) => {

     resolve('ok')

 })

 const p2 = new Promise((resolve, reject) => {

     resolve('okhaha')

 })

 const p3 = new Promise((resolve, reject) => {

     resolve('kobab')

 })

 const result = Promise.all([p1,p2,p3]);

console.log(result);

4.4  .race()

 Promise包含n个promise的数组,说明:返回一个promise,第一个完成的promise的结果状态就是最终的结果状态

```javascript

 const p1 = new Promise((resolve, reject) => {

     resolve('ok')

 })

 const p2 = new Promise((resolve, reject) => {

     resolve('jj')

 })

 const p3 = new Promise((resolve, reject) => {

     resolve('ll')

 })

 const result = Promise.race([p1,p2,p3]);

console.log(result);

```
 5、promise封装ajax

```javascript


 

```

 async 和await

```javascript

async 函数   await 后跟着一个promise对象

async function getData(){

    let hotpot = await getHotpot(); //拿到resolve传递出来的数据

    console.log(hotpot);

    let tea = await getTea();

    consloe.log(tea);

}

getData();

一.ajax的同源策略

Ajax请求限制:

Ajax 只能向自己的服务器发送请求。比如现在有一个A网站、有一个B网站,A网站中的 HTML 文件只能向A网站服务器中发送 Ajax 请求,B网站中的 HTML 文件只能向 B 网站中发送 Ajax 请求,但是 A 网站是不能向 B 网站发送 Ajax请求的,同理,B 网站也不能向 A 网站发送 Ajax请求。

**什么叫同源策略**

同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源

**同源策略的目的**

同源策略是为了保证用户信息的安全,防止恶意的网站窃取数据。最初的同源政策是指 A 网站在客户端设置的 Cookie,B网站是不能访问的。

随着互联网的发展,同源政策也越来越严格,在不同源的情况下,其中有一项规定就是无法向非同源地址发送Ajax 请求,如果请求,浏览器就会报错。


二.jsonp跨域

##### 使用JSONP解决同源限制问题

jsonp的原理:页面上的很多标签比如src,href,都不会受到同源策略的影响

有一些标签天生就有跨域能力,比如:img,link,iframe,script

jsonp就是利用`<script>`的src来实现跨域获取数据的,只支持get请求

jsonp 由两部分组成:回调函数和数据,回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据

jsonp 是 json with padding 的缩写,它不属于 Ajax 请求,但它可以模拟 Ajax 请求。

1. 将不同源的服务器端请求地址写在 script 标签的 src 属性中

   ```javascript

    <script src="www.example.com"></script>

   ```

2. 服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数。

   ```javascript

    const data = 'fn({name: "张三", age: "20"})';

    echo data;

   ```

3. 在客户端全局作用域

   ```javascript

   function fn(data){}

   ```

4. 在fn函数内部对服务器端返回的数据进行处理

   ```javascript

   function fn(data){

       console.log(data);

   }

   ```

整体实现思路:

1. 客户端需要将函数名称传递到服务器端

2. 将script请求的发送变成动态的请求。

```javascript

 <script>

  function fn(data){

     console.log(data);

 }

//  接收后端响应的数据

</script>

<script src="data.php?callback=fn"></script>

```

​    后端:

```javascript

<?php

    $cb = $_GET['callback']; //接收前端的参数:callback  fn

    $data = "i am back";

    echo $cb.'("'.$data.'")'; // fn('123')

?>

    

    echo '字符串'

```

高级版实现:

```javascript

 <script>

        function fn1(data) {

            console.log('客户端的fn函数被调用了');

            console.log(data);

        }

        function add(){

            // 创建srcipt标签

            var oSrc = document.createElement('script');

            oSrc.src = 'http://192.168.52.1/workspace/demo/code3/data.php?callback=fn1';

            document.body.appendChild(oSrc);

            // 监听script标签什么时间加载完成,

            oSrc.onload = function(){

                oSrc.remove();

            }

        }

    </script>

``

高级封装

```javascript

1. 客户端需要将函数名称传递到服务器端

2. 将script请求的发送变成动态请求

3. 封装jsonp函数,方便请求发送

```

  ```javascript

 <script>

        function add() {

            jsonp({

                url: 'http://192.168.52.1/workspace/data.php',

                data:{},

                success:function(data){

                    console.log(data);

                }

            })

        }

        function jsonp(options) {

            var script = document.createElement('script');

            var fn = 'myscript'+Math.random().toString().replace('.','');

            window[fn]=options.success;

            script.src = options.url+'?callback='+fn+getParams(options.data);

            document.body.appendChild(script);

            // 监听script标签什么时间加载完成,

            script.onload = function () {

                script.remove();

            }

        }

        function getParams(obj){

            var arr = [];

            for(var k in obj){

                  arr.push(k+'='+obj[k]);

            }

            return arr;

        }

    </script>

三.服务器端跨域

CORS:全称为 Cross-origin resource sharing,即跨域资源共享,它允许浏览器向跨域服务器发送 Ajax 请求,克服了 Ajax 只能同源使用的限制。

前端请求地址:

```javascript

http://192.168.52.1/workspace/day05/cros.php

```

后端设置:

```javascript

 Access-Control-Allow-Origin: 'http://localhost:3000'

 Access-Control-Allow-Origin: '*'

```

header(‘Access-Control-Allow-Origin: *’);

如果想设置只允许某个网站通过的话可以这样设置

header(’Access-Control-Allow-Origin: http://test.com‘); // 允许test.com发起的跨域请求,其他的都不通过

六. 请求天气预报

接口文档:

```javascript

      请求方式:GET     

      请求地址: 'https://wis.qq.com/weather/common',

     必要参数:

         province: "陕西省",

         city: "西安市",

         source:'pc',

         weather_type:'forecast_1h'

搜索框自动搜索

```javascript

<!DOCTYPE html>

<html>

<head>

    <title></title>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">

</head>

<body>

    <input type="text">

    <script src="./jsonp.js"></script>

    <script>

        

        var oTxt = document.querySelector('input')

        oTxt.oninput = function () {

            jsonp({

                type:'GET',

                url: 'https://suggest.taobao.com/sug',

                data: {

                    q: this.value,

                },

                success: function (data) {

                    console.log(data);

                }

            })

        }

    </script>

</body>

</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值