javascript中Promise深入理解

因为js是单线程的脚本语言,所以在执行代码时会先执行主程序中的代码,如果需要加载的程序,会先加载,待其加载完成后,将其丢到主程序中执行。
下面是一个简单的异步操作:

<!DOCTYPE html>
<html lang="cn">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>div{width: 200px;height: 200px;background: green;position: absolute;left:0px;}</style>
</head>
<body><div></div><script>function interval(callback,time){let id = setInterval(()=>{callback(id)},time)}interval((idC)=>{let div = document.querySelector("div");let left = parseInt(window.getComputedStyle(div).left);div.style.left = left+ 10+"px";if(left >=200){clearInterval(idC);}},100)console.log("2021");// 注意:在js的定时器中,定时器返回的值是定时器的编号。// 因为js是单线程的语言,所以在js中只会执行主程序,不断轮询主程序</script>
</body>
</html>

这里设置定时器,因为定时器需要等待,所以当该程序运行时,会将定时器模块丢到定时器模块加载,此时主程序会将主程序中的文件先执行,待定时器模块加载完毕后,会将其丢到主程序中等待执行。此时主程序会不断地进行轮询操作。
下面是图片加载操作:

<!DOCTYPE html>
<html lang="cn"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>function imageLoad(src, resolve, reject) {let image = new Image();image.src = src;image.onload = resolve(image);image.onerror = reject;}setTimeout(() => {imageLoad('./img_1.jpg', function () {document.body.appendChild(arguments[0]);console.log("图片加载成功");}, () => {console.log("图片加载失败");})}, 1)console.log("图片加载的小demo");// 这里是异步处理,首先图片加载需要耗时,所以会在另一个内存空间内进行处理,当处理完成后,处理的结果会返回主程序// 此时javascript会优先处理主程序中的程序,并且会不断的轮询其他完成了的程序</script>
</body></html>

解析:这里是异步处理,首先图片加载需要耗时,所以会在另一个内存空间内进行处理,当处理完成后,处理的结果会返回主程序。此时javascript会优先处理主程序中的程序,并且会不断的轮询其他完成了的程序。
Promise简介:

<script>new Promise((resolve,reject)=>{resolve("解决")}).then((value)=>{console.log("成功1");},()=>{console.log("失败1");}).then((value)=>{console.log("成功2");},()=>{console.log("失败2");})console.log("这里是主程序");
</script>

解析:这里是Promise对象设置一个异步操作,传入两个参数表示状态,只有当状态改变的时候才能执行下面的then操作,不设置状态表现是pending状态。当设置状态是resolve时表示状态解决,当设置reject时表示失败状态。同时then中传入的两个参数是两个处理函数,分别是对成功和失败的情况下进行处理的操作。
②上面代码中的最后一个是主程序,上面的Promise是微程序,我们上面的代码中的图片加载以及定时器操作都是宏程序。主程序的处理次序要优先于微程序,微程序的处理次序要优先于宏程序。
各类程序的优先次序

<script>
setTimeout(function(){console.log("setTimeOut");},0);new Promise((resolve,reject)=>{resolve();console.log("Promise");}).then(()=>{console.log("成功");})console.log("主程序");// 上面几个顺序是:// Promise// 主程序// 成功// setTimeout</script>

解析:上面程序中的定时器会先放到宏任务中进行加载,Promise中的console.log(“Promise”);会放到主程序中进行加载,然后通过状态改变开启一个微任务,由于主程序中的操作优先于微程序中的任务,优先于宏任务中的任务。所以上面便是最终的结果。

<script>
new Promise((resolve)=>{console.log("哈哈哈哈");setTimeout(function(){resolve();console.log("setTimeOut");},0)}).then(()=>{console.log("成功");})console.log("主程序");// 打印的结果是// 哈哈哈哈// 主程序// setTimeout// 成功
</script>

解析:在promise中刚开始的哈哈哈哈语句是放到主程序中执行。并且其中存放了一个setTimeOut,所以会放到宏任务中。在宏任务中的内容开始到主程序执行的时候,此时setTimeOut语句就会在主程序中执行,但是resolve()这样一个微任务程序,会在微任务序列中等待执行,所以最后执行成功。

<script>let p1 = new Promise((resolve,reject)=>{// resolve("成功aaaa");reject("失败")});console.log(p1);let p2 = new Promise((resolve,reject)=>{resolve(p1);}).then((msg)=>{console.log(msg);},()=>{console.log('失败');});</script>

解析:当一个Promise对象作为一个参数传入下一个Promise对象中.如果传入的promise对象为失败状态,则下一个Promise也是失败状态。第二:promise()对象状态一旦确定,就不可以更改
Promise中的then

<script><script>new Promise((resolve,reject)=>{resolve("成功了");// reject("失败了")}).then(value=>{console.log(value);},reason=>{console.log(reason);})// 解析:只有当resolve或者reject执行的时候,才能将程序放置到微任务程序中// 如果仅仅想要讨论一种状态,另外一种状态可以省略,必要时可以使用null。</script>
</script>

解析:只有当resolve或者reject执行的时候,才能将程序放置到微任务程序中。如果仅仅想要讨论一种状态,另外一种状态可以省略,必要时可以使用null。
then的状态

<script><script>let p1 = new Promise((resolve, reject) => {// resolve("成功");reject("失败1");})let p2 = p1.then((value) => {console.log("成功2");}, (reason) => {console.log("失败2");}).then((value)=>{console.log("成功3");},(reason)=>{console.log("");})//失败2//成功3
</script>

这里打印的结果是失败2,成功3,p1的then接收的一个reject的结果,但是第二的then当没有设置状态改变的时候,默认的状态是成功的状态。
对then返回的处理

<script>
//一、这里的then直接打印出结果
new Promise((resolve,reject)=>{resolve("成功了");}).then(value=>{console.log(value);},reason=>{console.log(reason);})
//二、then默认是成功状态new Promise((resolve,reject)=>{resolve("成功了");}).then(value=>{return "我是dl"},reason=>{console.log(reason);}).then(value=>{console.log(value);})
//三、一个Promise对象对应一个then函数 当Promise处于pedding状态,下面的then就会进行等待new Promise((resolve, reject) => {resolve("成功了")}).then(value => {return new Promise((resolve, reject) => {// resolve("我是dl");reject("失败了不是")})}, reason => {console.log(reason);}).then(value => {console.log(value);}, reason => {console.log(reason);})//四、 当设置定时器的时候,后面的then必须设置到等到状态才可以执行new Promise((resolve, reject) => {resolve("成功了")}).then(value => {return new Promise((resolve, reject) => {// resolve("我是dl");setTimeout(function () {reject("失败了不是")}, 3000)})}, reason => {console.log(reason);}).then(value => {console.log(value);}, reason => {console.log(reason);})//五、 一个Promse对应着一个then,后面的then(),就是对Promise的处理new Promise((resolve, reject) => {resolve("成功了")}).then(value => {return new Promise((resolve, reject) => {reject("失败了不是")}).then(null, r => {return new Promise((resolve, reject) => {resolve("hhhhhh")})});}, reason => {console.log(reason);}).then(value => {console.log(value);}, reason => {console.log(reason);})
</script>

其他类型的Promise封装

<script>
//一、正常的使用Promise对象new Promise((resolve,reject)=>{resolve("成功了");}).then(value=>{return new Promise((resolve,reject)=>{resolve("成功哈哈哈")})},reason=>{console.log(reason);}).then(value=>{console.log(value);})//二、使用对象字面量来封装new Promise((resolve,reject)=>{resolve("成功");}).then(value=>{return { //这里使用return返回一个Promise对象then(resolve,reject){resolve("哈哈哈")}}},reason=>{console.log(reason);}).then(value=>{console.log(value);})
//三、使用对象字面量来封装new Promise((resolve,reject)=>{resolve("成了")}).then(value=>{class dh{then(resolve,reject){reject("拒绝")} }return new dh;},reason=>{console.log(reason);}).then(value=>{console.log(value);},reason=>{console.log(reason);})//四、使用静态方法进行封装new Promise((resolve,reject)=>{resolve("成了");}).then(value=>{class hd{static then(resolve,reject){resolve("哈哈哈哈");}}return hd;},reason=>{console.log(reason);}).then(value=>{console.log(value);},reason=>{console.log(reason);})
</script>

对ajax异步操作进行处理

<script>
<!DOCTYPE html>
<html lang="cn">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function ajax(url){return new Promise((resolve,reject)=>{let xhr = new XMLHttpRequest();xhr.open("GET",url);xhr.send();xhr.onload = function(){if(this.status == 200){resolve(this.response);}else{reject("加载错误")}}xhr.onerror = function(){reject(this);}})}ajax('http://127.0.0.1:5000/user/dl').then(value=>{// value = eval('(' + value + ')');return ajax("http://127.0.0.1:5000/id/201902091").then(value=>{console.log(value);},reason=>{console.log(reason);});console.log("http://127.0.0.1:5000/id/"+value['id']);},reason=>{console.log(reason);})</script>
</body>
</html>
</script>

这里的程序,只有等到上一级的操作完成后 ,才能进行下一次操作。
对Promise中失败的处理

<script>
//一、这里是直接通过使用reject进行错误返回new Promise((resolve,reject)=>{reject("失败")}).then(value=>{console.log(value);},reason=>{console.log(reason);})//二、当一些语法错误之类的,js会直接返回reject对象.new Promise((resolve, reject) => {hs+10;}).then(value => {console.log(value);}, reason => {console.log(reason.message);})//三、可以自己去抛出错误,这样也会返回rejectnew Promise((resolve, reject) => {throw new Error("shibai")}).then(value => {console.log(value);}, reason => {console.log(reason.message);})//四、new Promise((resolve, reject) => {try{hs+10;}catch{console.log("这里出现错误");}}).then(value => {console.log(value);}, reason => {console.log(reason);})
//五、new Promise((resolve,reject)=>{reject("失败")}).then(value=>{return new Promise((resolve,reject)=>{resolve("chengg")})},reason=>{console.log(reason);}).catch(error=>{console.log(error);})
//catch可以解决reject出现的错误,可以解决前面所有出现的错误,但是不能解决.其后面出现的错误,如果是前面出现错误被自身的reject()回调函数解决,则后面则不接收错误</script>

javascript中Promise深入理解(一)相关推荐

  1. javascript中 (function(){})();如何理解?

    javascript中 (function(){})();如何理解? javascript中: (function(){})()是匿名函数,主要利用函数内的变量作用域,避免产生全局变量,影响整体页面环 ...

  2. 谈谈JavaScript中function多重理解

    JavaScript 中的 function 有多重意义.它可能是一个构造器(constructor),承担起对象模板的作用: 可能是对象的方法(method),负责向对象发送消息.还可能是函数,没错 ...

  3. Javascript中你必须理解的执行上下文和调用栈

    执行上下文在 JavaScript 是非常重要的基础知识,想要理解 JavaScript 的执行过程,执行上下文是你必须要掌握的知识.否则只能是知其然不知其所以然. 理解执行上下文有什么好处呢? 它可 ...

  4. javascript中的面向对象理解(一)

    一.注意:提到"面向对象"这一概念,众所周知,javascript中的面向对象思想与其他的编程语言(例如:PHP.Java等)是有着很大区别的.因此,我们先复习下,传统意义上,面向 ...

  5. javaScript中Promise详解

    ES2015正式发布(也就是ES6,ES6是它的乳名),其中Promise被列为正式规范.作为ES6中最重要的特性之一,我们有必要掌握并理解透彻.本文将由浅到深,讲解Promise的基本概念与使用方法 ...

  6. JavaScript中Promise 使用详解

    Part 01 - Promise 概述 Promise 一种更优的异步编程统一方案 传统的异步编程如ajax:是通过回调函数来进行请求后的一系列执行. 但是如果直接使用传统的回调的方式去完成复杂的异 ...

  7. javascript 中的nodeList理解

    NodeList是一中类数组对象,用于保存一组有序的节点 可以通过方括号来访问NodeList的值,他有item()方法与length属性. 他并不是Array的实列,没有数组对象的方法. 如何拿到n ...

  8. javascript中bind函数理解

    bind函数会创建一个新的函数体: bind函数第一个参数是改变this的指向,第二个以及之后的每个参数都是传进去原来的函数参数: bind函数是在Function原型上的: bind 函数可以用来递 ...

  9. JavaScript中事件回顾

    事件其实在第一次学习JavaScript的时候就接触了,一行非常简单的代码 alert('Hello JavaScript!!!')就诠释了什么是事件.事件是什么呢?事件在基于浏览器编程的语言Java ...

  10. JavaScript中undefined详解

    目录 一.前言 二.undefined的特点 1.undefined既是JavaScript中的原始数据类型之一,也是一个原始值数据 2.undefined是全局对象上的一个属性 3.undefine ...

最新文章

  1. 一个有趣的案例 | 页面扭曲矫正
  2. Only call `sigmoid_cross_entropy_with_logits` with named arguments解决
  3. andrioid 桌面
  4. Cisco Catalyst 4500
  5. java的地位和优势,Java语言之所以能持续占领霸主地位 这些优势功不可没
  6. linux进程map,LInux环境运行mapReduce程序
  7. python爬虫入门 - 代码、案例集合
  8. mac怎么查node版本_py2neo基本操作(v4版本,亲测有效)
  9. python pytest框架
  10. css grid随页面大小_你现在可以玩下这 5 个 CSS 新功能
  11. 从Windows复制文件到Linux显示乱码问题
  12. Tensorflow-pb保存与导入
  13. PyTorch并行与分布式(三)DataParallel原理、源码解析、举例实战
  14. 调试器---镜像劫持
  15. 主板电源接口测试软件,雷电接口加入! Intel原厂血统Z77测试
  16. 关于navicat设置主键属性identity
  17. 如何通过西部数据JBOD 分组功能避免数据安全问题?
  18. Linux RabbitMQ - CLI tool fails to authenticate with the server
  19. 苹果状态栏HTML,有关HTML5页面在iPhoneX适配问题
  20. golang cpuprofile分析

热门文章

  1. 双层pdf解析 java_java转双层pdf
  2. [转]程序员资料整理
  3. 104规约 scada
  4. DOA算法1:MUSIC算法(二)
  5. 计算机组成原理课后答案(唐朔飞第三版) 第二章
  6. Minitab正态能力分析算法资源合集
  7. 显示器最大分辨率测试软件,液晶显示器分辨率快速设置工具
  8. 用友U8远程接入解决方案用户手册下载
  9. 从ST官网获取STM32 AD封装库(包含原理图库和PCB库)详细教程
  10. 利用salt防范MD5字典攻击