JS异步编程,回调函数与promise
Posted 职坐标在线
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS异步编程,回调函数与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); //12
11 return new Promise(function(resolve,reject){
12 setTimeout(() => {
13 console.log(21); //21
14 resolve(22);
15 }, 1000);
16 });
17 }).then(function(value){ //回调函数3
18 //上一个promise resolve()后执行
19 console.log(value); //22
20 setTimeout(() => {
21 console.log(31); //31
22 }, 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); //12
11 setTimeout(() => {
12 console.log(21); //21
13 }, 1000);
14 return 22;
15 }).then(function(value){ //回调函数3
16 //上一个promise resolve()后执行
17 console.log(value); //22
18 setTimeout(() => {
19 console.log(31); //31
20 }, 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/
更多关于web前端、Java、大数据、人工智能、物联网等学习资源请加小职微信获取:
长按二维码加小职吧
在线等你
以上是关于JS异步编程,回调函数与promise的主要内容,如果未能解决你的问题,请参考以下文章
Node.js&Promise的新理解&记一次异步编程的错误尝试