博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS异步编程,回调函数与promise
阅读量:4988 次
发布时间:2019-06-12

本文共 3120 字,大约阅读时间需要 10 分钟。

  Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

  ES6之前,JavaScript中异步编程分为3类:DOM事件(如onclick)、网络请求(如ajax)、定时器(setTimeout/setInterval)。他们均使用回调函数来进行异步调用。当回调函数中嵌套了回调函数,甚至是多层回调时,编码就不够直观了。而使用Promise就能通过同步的编码方式实现异步调用。

1.多层回调:使用setTimeout()函数执行3层嵌套的异步回调,编码不直观

1   function async(){ 2     setTimeout(function(){  //回调函数1 3       console.log(1);   4       setTimeout(function(){  //回调函数2 5         console.log(2); 6         setTimeout(function(){  //回调函数2 7           console.log(3); 8         },1000); 9       },1000);10     },1000)11   }12 13   async();14 15   //调用结果:1s后打印1 2s后打印2 3s后打印3

 

2.promise:以同步顺序编码来执行3次异步回调

通过return new Promise(),如果该promise中含有异步调用(setTimeout),则会等到异步调用中执行resolve()时才会执行后面的then函数。

1   new Promise(function(resolve,reject){ 2     //立即执行 3     console.log('new promise'); 4     setTimeout(() => {  //回调函数1 5       console.log(11);  //11 6       resolve(12);  //返回value给下一个then函数 7     }, 1000); 8   }).then(function(value){  //回调函数2 9       //上一个promise resolve()后执行10       console.log(value);  //1211       return new Promise(function(resolve,reject){12         setTimeout(() => {13           console.log(21);  //2114           resolve(22);15         }, 1000);  16       });17     }).then(function(value){  //回调函数318       //上一个promise resolve()后执行19       console.log(value);  //2220       setTimeout(() => {21         console.log(31);   //3122       }, 1000);  23     });24 25   //执行结果:立即打印new promise,1s后打印11/12,2s后打印21/22,3s后打印31

 

3.如果then的回调函数中没有声明式的return new Promise(); 那么return会自动返回一个新的promise,所以也可以链式执行then函数。

return自动返回的promise中并没有异步操作(setTimeout没有在promise中),所以后面的then函数是立即执行的。

可以参考MDN中关于then返回值的说明:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

1   new Promise(function(resolve,reject){ 2     //立即执行 3     console.log('new promise'); 4     setTimeout(() => {  //回调函数1 5       console.log(11);  //11 6       resolve(12);  //返回value给下一个then函数 7     }, 1000); 8   }).then(function(value){  //回调函数2 9       //上一个promise resolve()后执行10       console.log(value);  //1211       setTimeout(() => {12           console.log(21);  //2113         }, 1000);  14       return 22;15     }).then(function(value){  //回调函数316       //上一个promise resolve()后执行17       console.log(value);  //2218       setTimeout(() => {19         console.log(31);   //3120       }, 1000);  21     });22 23 //执行结果:立即打印new promise,1s后打印11/12/22,2s后打印21/31

 

4.异步编程原理:

  JS是单线程指的是它的执行栈是单线程的(即JavaScript引擎的线程),称为主线程。JS 会创建一个类似于 while (true) 的循环,每执行一次循环体的过程称之为 Tick。每次 Tick 的过程就是查看任务队列中是否有待处理任务(DOM事件/网络请求/定时器的回调函数),如果有则取出相关回调函数放入执行栈中由主线程执行。

  异步操作会将相关回调添加到任务队列中。而不同的异步操作添加到任务队列的时机也不同,onclick 由浏览器内核的 DOM Binding 模块来处理,当事件触发的时候,回调函数会立即添加到任务队列中。setTimeout 会由浏览器内核的 timer 模块来进行延时处理,当时间到达的时候,才会将回调函数添加到任务队列中。ajax 则会由浏览器内核的 network 模块来处理,在网络请求完成返回之后,才将回调添加到任务队列中。

  浏览器内核实现允许多个线程异步执行JavaScript引擎的线程外,还存在事件触发进程、计时器触发进程、http请求线程等,他们与JavaScript引擎的线程是互不影响的,不会造成阻塞。即JavaScript引擎的线程阻塞后,事件仍然会被触发,但只是事件的回调函数无法添加到任务队列,或者无法从任务队列添加到执行栈中。

异步原理参考链接:https://blog.csdn.net/qdq2014/article/details/72383725/

转载于:https://www.cnblogs.com/shuqiao/p/10040885.html

你可能感兴趣的文章
C - 继续畅通工程 最小生成树
查看>>
centos7 更换jdk版本
查看>>
Android开发训练之第五章第七节——Transmitting Network Data Using Volley
查看>>
Java基础知识强化之集合框架笔记01:集合的由来与数组的区别
查看>>
Java基础知识强化之IO流笔记71:NIO之 NIO的(New IO流)介绍
查看>>
Android(java)学习笔记31:泛型高级之通配符
查看>>
Eclipse 修改workspace默认的字符集为 utf-8
查看>>
laravel artisan 工具心得
查看>>
软工作业 4:结对项目之词频统计——基本功能
查看>>
linux vim vi编辑时撤销输入操作
查看>>
java utils
查看>>
maven打包
查看>>
CSS
查看>>
初学springboot, 如何快速使用maven搭建springboot项目呢
查看>>
POJ 3380 最大流
查看>>
iOS学习之 plist文件的读写
查看>>
写的一些推广方法 拿出来分享下
查看>>
【公告】CSDN个人空间将于2014年4月20日全新改版上线
查看>>
C#:MVC打印PDF文件
查看>>
在学习mybatis中的接口是发生错误Type interface com.souvi.ibatis.xxxMapper is not known to the MapperRegistry...
查看>>