js[异步编程理解(promise/回调函数/async-await)、异步转同步的方式]探究

Javascript语言的执行环境是"单线程",而Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)
首先得意识到一个问题

何为异步编程?何为同步编程?

直接上网上的优秀文章:
https://zhuanlan.zhihu.com/p/94686991

总之

同步编程:就是机械一行一行的执行代码直到代码结束,一旦出现问题就执行不下去了
异步编程:就是机械执行到异步代码的时候会将这个代码内容暂时挂起,然后继续执行下面内容,当挂起的内容得到响应的时候,又返回来继续执行这个异步代码之后的内容。

js常见的异步操作有:

  1. setTimeout (setInterval)
  2. AJAX
  3. 事件绑定(如:.on,.bind,.listen,.addEventListener,.observe)
  4. 观察者模式(例如:websocket中就有发布和订阅之类的操作)
  5. promise 是一个异步操作,但是它是一个异步操作的解决方案,即保存着异步操作的结果,可以把异步函数以同步函数的形式写出来
  6. async/await — 使用generator的语法糖,可以理解为是generator的一种改进
  7. generator函数 — 使用promise的语法糖,可以理解为是promise的另一种拓展

异步转同步的方式

第一种方式:回调函数

回调函数就是将一个函数当作另一个主函数的参数来使用的函数。

function test2(){
    
    //回调函数
	console.log('执行了test2');
}
function test1(callback){
    
     //(主函数)
	console.log('执行了test1');
   setTimeout(function () {
    
    
     callback();
   }, 1000);
}
// 执行
test1(test2);

执行结果
在这里插入图片描述
解读:回调函数是传统的一种异步编程解决方案,其原理就是将一个函数当作参数传递到另一个主函数中,当主函数执行完自身的内容之后,在运行传递进来的回调函数。这样就达成了类似异步的效果。
缺点:一个任务只能有一个回调函数
用法:回调函数在js中用的还是比较多的,例如:jsonp、ajax、一些常见的需要传递函数当参数来处理一些后续内容的操作
回调函数分为异步回调和同步回调,其实区别就在于主函数中是否执行了异步操作而已

第二种方式:promise/async-await/generator的基本使用

es6中为了解决异步编程,出现了三种类似的用于解决异步操作的方案。
由上面已经直到setTimeout是一种异步操作了,因此这里的例子可以将每一个setTimeout拟作一次接口请求。
promise的基础用法
基本使用需求:存在两个函数a()、b(),我需要在a()函数所有内容执行完毕之后在执行b()函数,然后a()函数中又存在异步操作(获取数据),因此如果我按常规顺序执行a()、b(),就会导致执行b的之后出现数据内容不存在的情况(a是异步)。因此可以使用promise来处理
基本使用示例:单个异步操作完成后才会进行后续操作
在这里插入图片描述
使用将a函数的返回值内容加上new Promise((resolve,reject)=>{}),然后当内部的异步操作完成后就执行resolve,如果出现异常就执行reject即可。
此时,可以进行a().then()操作执行b()即可。resolve对应的是.then()、reject对应的是.catch();
在这里插入图片描述
这样就达成了理想的效果,先执行a函数,然后执行b函数。

async-await的基础用法

  1. async 函数和普通函数一样执行,是generator的语法糖。
  2. async函数的返回值是 Promise 对象,可以用.then方法指定下一步的操作,return语句返回的值,会成为then方法回调函数的参数
 async function test() {
    
    
    return 'hello world'
}
test().then(result => {
    
    
    console.log(result);
})

3.基本使用示例:多个异步操作完成后才会进行后续操作
在这里插入图片描述
在这里插入图片描述
await后面的函数建议 返回 Promise对象(即return new Promise((resolve,reject)=>{})) 并且主动调用resolve()才能够进行后续的then或者是后续的await操作,倘若是执行了reject(reject的参数会被catch方法的回调函数接收到)或者throw抛出错误之类的就会导致当前执行中断。

注意1:await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try…catch代码块中。
在这里插入图片描述
注意2:多个await命令后面的异步操作,如果不存在先后关联,最好让它们同时触发。不然会增加耗时
在这里插入图片描述
这样做的好处就是,如果两个await直接运行则需要2秒的时间才会运行后续的内容,但是像这样处理一下,两个就会同时开始,即只需要1秒就可以运行后续的内容了。

generator的使用
https://es6.ruanyifeng.com/#docs/generator

猜你喜欢

转载自blog.csdn.net/lxy869718069/article/details/106680462