Promise

目录

一、定义

Promise 优缺点

二、三种状态

三、基本用法

四、模拟异步

案例:

示例:多少s后打印一句话

五、执行步骤

 六、json对象数据格式

1. 什么是 JSON?

2.   JSON 语法规则

 3.  JSON 对象

4.   JSON 数组

5.  相关函数

6.  示例 

 七、封装ajax

1.  什么是ajax

2.  ajax的工作原理

2.1、创建 XMLHttpRequest 对象

2.2、向服务器发送 

2.3、 服务器响应

onreadystatechange 事件

使用回调函数

3.  示例

八、 Proimse.prototype.then

九、 Promise.prototype.catch()


一、定义

Promise是异步编程的一种解决方案,可以替代传统的解决方案--回调函数和事件。ES6统一了用法,并原生提供了Promise对象。作为对象,Promise有一下两个特点:

  1. 对象的状态不受外界影响。

Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

     2.一旦状态改变了就不会在变,也就是说任何时候Promise都只有一种状态。

Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。

Promise 优缺点

有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。

Promise 也有一些缺点。首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

二、三种状态

Pending状态(进行中)、Fulfilled状态(已成功)、 Rejected状态(已失败)

一旦发生改变就只有一种状态:Pending -> Fulfilled  Pending -> Rejected。

三、基本用法

Resolve,用来接收完成状态,

reject用来接收失败的状态。

  //Promise 通过new关键词 回调函数有两个形参 第一个:resolve(成功) reject(失败的方法)
  //resolve reject这两个可以改变Promise实例的状态
  let  promise=new Promise(function(resolve,reject){
      let flag=true;
      if(flag){
          resolve('成功');
      }else{
          reject('失败');
      }
 })
//获取 Promise的值,有两个参数,第一个参数:回调函数显示成功的状态,第二个是显示失败的状态
  promise.then(resolve=>console.log(resolve),
               reject=>console.log(reject)
  )

 

说明then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。这两个函数都是可选的,不一定要提供。它们都接受Promise对象传出的值作为参数。 

四、模拟异步

案例:

       function timeout(ms){
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    console.log(ms+'秒后打印');
                },ms)
            })
        }
        console.log(1);
        setTimeout(()=>{
            console.log('1秒后打印');
        },0);
        console.log(2);

 打印顺序为什么不是打印出 1 后不是接着打印setTimeout函数,而是直接打印下面的2?

        console.log(1);

        console.log(2);

        setTimeout(()=>{

            console.log('1秒后打印');

        },0);

       

 其结果与之前一样,与代码的顺序无关

 setTimeout 只是在模拟异步,其代码运行到它时还是单线程运行,不是多线程;在运行代码时,把 setTimeout 下调了,调至2 后面,代码顺序如上面灰色块里的代码顺序,在其他代码执行完后执行,与变量上提原理一样。

示例:多少s后打印一句话

        function timeout(ms){
            console.log(2);
            return new Promise((resolve,reject)=>{
                console.log(3);
                setTimeout(()=>{
                    console.log(6);
                    console.log(ms+'秒后打印');
                    resolve('end');
                },ms)
            })
        }
        console.log(1);
        const mypromise=timeout(2000);
        console.log(4);
        mypromise.then((resolve)=>{
            console.log(resolve);
        })
        console.log(5);

五、执行步骤

        function timeout(ms){
            console.log(2);
			return new Promise(function(relove,reject){
			    setTimeout(()=>{
				    console.log(3);
				    relove(4);
				},ms);
			})	
		}
	    console.log(1);
		let res =  timeout(3000);
		res.then(relove=>console.log(relove))

 说明:Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以4最后输出。

 六、json对象数据格式

1. 什么是 JSON?

  • JSON 英文全称 JavaScript Object Notation
  • JSON 是一种轻量级的数据交换格式。
  • JSON是独立的语言 *
  • JSON 易于理解。

2.   JSON 语法规则

  • 数据为 键/值 对。
  • 数据由逗号分隔。
  • 大括号保存对象
  • 方括号保存数组

 3.  JSON 对象

JSON 对象保存在大括号内。

就像在 JavaScript 中, 对象可以保存多个 键/值 对:

{"name":"Runoob", "url":"www.runoob.com"}

4.   JSON 数组

JSON 数组保存在中括号内。

就像在 JavaScript 中, 数组可以包含对象:

"sites":[ {"name":"Runoob", "url":"www.runoob.com"},

             {"name":"Google", "url":"www.google.com"},

             {"name":"Taobao", "url":"www.taobao.com"}

]

在以上实例中,对象 "sites" 是一个数组,包含了三个对象。

每个对象为站点的信息(网站名和网站地址)。

5.  相关函数

函数描述
JSON.parse()用于将一个 JSON 字符串转换为 JavaScript 对象。
JSON.stringify()用于将 JavaScript 值转换为 JSON 字符串。

 

 

 

6.  示例 

        var Person='{"realname":"张三","age":19}';
        const P1=JSON.parse(Person);
        console.log(P1.realname);  //张三

        var persons='["张三","李四"]';
        const p1=JSON.parse(persons);
        console.log(p1);  //["张三", "李四"]
        
        var P2={realname:'张三',age:19};
        console.log(JSON.stringify(P2));  //{"realname":"张三","age":19}

 七、封装ajax

1.  什么是ajax

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

2.  ajax的工作原理

  • 创建 XMLHttpRequest 对象
  • 向服务器发送请求
  • 服务器响应

2.1、创建 XMLHttpRequest 对象

XMLHttpRequest 是 AJAX 的基础。

所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。

创建 XMLHttpRequest 对象的语法:const ajax=new XMLHttpRequest();

老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:

 const ajax=new ActiveXObject("Microsoft.XMLHTTP");

为了应对所有的现代浏览器,包括 IE5 和 IE6,请检查浏览器是否支持 XMLHttpRequest 对象。如果支持,则创建 XMLHttpRequest 对象。如果不支持,则创建 ActiveXObject  

2.2、向服务器发送 

 XMLHttpRequest 对象用于和服务器交换数据

如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法:

xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();
方法描述
open(method,url,async)

规定请求的类型、URL 以及是否异步处理请求。

  • method:请求的类型;GET 或 POST
  • url:文件在服务器上的位置
  • async:true(异步)或 false(同步)
send(string)

将请求发送到服务器。

  • string:仅用于 POST 请求

 

 

 

 

GET 还是 POST? 

与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。

然而,在以下情况中,请使用 POST 请求:

  • 不愿使用缓存文件(更新服务器上的文件或数据库)
  • 向服务器发送大量数据(POST 没有数据量限制)
  • 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

 

 异步 - True 或 False?

AJAX 指的是异步 JavaScript 和 XML(Asynchronous JavaScript and XML)。

XMLHttpRequest 对象如果要用于 AJAX 的话,其 open() 方法的 async 参数必须设置为 true

对于 web 开发人员来说,发送异步请求是一个巨大的进步。很多在服务器执行的任务都相当费时。AJAX 出现之前,这可能会引起应用程序挂起或停止。

通过 AJAX,JavaScript 无需等待服务器的响应,而是:

  • 在等待服务器响应时执行其他脚本
  • 当响应就绪后对响应进行处理

2.3、 服务器响应

onreadystatechange 事件

当请求被发送到服务器时,我们需要执行一些基于响应的任务。

每当 readyState 改变时,就会触发 onreadystatechange 事件。

readyState 属性存有 XMLHttpRequest 的状态信息。

在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。

当 readyState 等于 4 且状态为 200 时,表示响应已就绪

使用回调函数

回调函数是一种以参数形式传递给另一个函数的函数。

如果您的网站上存在多个 AJAX 任务,那么您应该为创建 XMLHttpRequest 对象编写一个标准的函数,并为每个 AJAX 任务调用该函数。

该函数调用应该包含 URL 以及发生 onreadystatechange 事件时执行的任务(每次调用可能不尽相同)

3.  示例

  ajax.html文件

        const ajax=new XMLHttpRequest();
        //console.log(ajax.readyState);  //0
        //1:用get打开请求地址
        ajax.open("GET","http://127.0.0.1:5500/test.json");
        //console.log(ajax.readyState);  //1
        2:发送请求
        ajax.send();
        //console.log(ajax.readyState);  //1
        ajax.onreadystatechange=()=>{
            if(ajax.readyState == 4){//xml的状态
                //console.log('服务请求完成');
                if(ajax.status==200){//代表成功
                    const data=JSON.parse(ajax.response);
                    console.log(data);
                }else{
                    console.log("请求失败");
                }
            }
        }

 test,json文件

{
    "code":"200",
    "message":"人员列表信息",
    "lists":[
        {
            "name":"张三1",
            "sex":"男",
            "age":"30"
        },
        {
            "name":"小红",
            "sex":"女",
            "age":"22"
        }
    ]
}

 在运行过程中出现的问题--关于获取  test,json文件的路径

在获取浏览器窗口的路径时,要注意跨域问题。

用 Open In Default Browser 打开,可获取的路径是错误

file:///C:/Users/28411/Desktop/lesson-practice/Ajax.html

 用 Open with Live Server 打开所获得的路径才是正确

http://127.0.0.1:5500/Ajax.html

此获得的路径在你的 test,json文件 和 ajax.html文件 在同一文件夹下时可以直接修改路径后缀Ajax.html 

用promise封装

           function sendajax(url){	
				return  new Promise((resolve,reject)=>{	
					const Obj =  new XMLHttpRequest();
					Obj.open("GET",url);
					Obj.send();
					Obj.onreadystatechange = ()=>{	
						if(Obj.readyState==4){
							
							if(Obj.status==200){//http状态码
								const data = JSON.parse(Obj.response);
								resolve(data);
							}else{
								reject("数据请求失败...");
							}	
						}	
					}
				})	
			}
			const MyPromise = sendajax("http://127.0.0.1:5500/test.json");
			MyPromise.then((resolve)=>{
				console.log(resolve);
			})

 

八、 Proimse.prototype.then

Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,参数可选。

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。根据这一特性我们可以采用链式 

            function demo(){
                return new Promise((resolve)=>{
                    resolve('hello');
                })
            }
            let Mydemo=demo();
            
                Mydemo.then((resolve)=>{
                console.log(resolve); //hello
                return resolve+'2';
            }).then((resolve)=>{
                console.log(resolve); //hello2
            })

 

九、 Promise.prototype.catch()

Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

Promise 对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个 catch 语句捕获。

            function demo(){
                return new Promise((resolve,reject)=>{
                    resolve('hello');
                })
            }
            let Mydemo=demo();
            Mydemo.catch((reject)=>{
                console.log(reject);
            })

只有在 发生错误时才能捕获到

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值