js异步编程: Promise, async, await

        async的中文意思是异步async实际上是一个语法糖,修饰的对象是一个函数,用来说明该方法是异步类型。。

        异步其实就是同时做多件事情,即并发。比如js的定时器方法就是一个异步型,假如一个定时器定时10秒,那么在这10秒内,js程序会继续从定时器代码处继续向下执行。

        async经常与await一起使用。 他们组合使用的最大作用就是:将几个具有前后依赖关系的异步操作变为同步运行。

        async和await的底层是promise。是es2017出的,是对promise,generaor等函数的语法封装。

        参考地址:地址。

目录

0,简述js程序的执行过程

1,大致的执行过程

2,什么是回调函数?

1,async将一个函数标记为异步函数

2,程序上下代码存在依赖关系时的await写法

3,程序上下代码不存在依赖关系时的await写法

4,不能使用forEach或map等方法遍历执行await修饰的函数

5,await不能修饰普通函数和方法


0,简述js程序的执行过程

1,大致的执行过程

        js是解释器类型的语言,类似于python的全局解释器锁,js天生的是单线程执行代码的,既然是单线程,那么就只有一个主线程。

        一个程序由语句,函数,语句块构成。函数又分为函数声明与函数调用,只有函数被调用才会执行函数。而在异步编程中,函数又分为普通同步函数和异步函数。

        所以js从上到下同步执行的过程遇到需要执行异步函数该怎么办?答案是遇到普通函数直接执行,遇到异步函数扔到事件队列里面。等到主线程将同步代码和普通同步函数执行完毕之后,再去执行事件队列里面的异步函数。

        这么做的原因就是单线程的js不可能另开线程去执行异步函数,也不可能让主线程去执行异步函数。注:线程是系统分配资源的最小单位,在上一级他们属于同一个进程,js的这种单线程模式不会产生过多的上下文切换开销,效率高。

        但是在队列里面的异步函数却是有方法实现并发运行的。

2,什么是回调函数?

        需要等待一段事件之后才能运行的函数。比如定时器的第一个参数就是函数,被称为回调函数,在定时完成之后才能去执行这个回调函数。

1,async将一个函数标记为异步函数

        异步函数的概念:若某个函数的返回值是一个Promise对象,则这个函数为一个异步函数。在js中比较常用的异步函数就是定时器setTimeout。

        在一个普通函数前面加上async就说明这个函数为异步类型,在这里不用关心async改变了这个函数什么,这只是一种语法形式而已,目的是将这个函数塞进事件队列里面。

        这里只需要知道js从上往下遇到异步函数该怎么做,关于js执行过程中遇到异步函数该怎么办,看这篇文章。这里。

        在async修饰的函数里面我们一般会调用其他的异步函数。

//演示用例,实际上是这样的“await 异步函数1();”
async function f() {
    异步函数1();
    异步函数2();
    异步函数3();
}

2,程序上下代码存在依赖关系时的await写法

        await的修饰对象也是一个异步函数,他会等待异步函数返回结果之后再去执行他下面的代码。

//演示写法
async function f() {
    result1 = await f1();
    result2 = await f2(result1);
    return result3 = await f3(result2);
}

3,程序上下代码不存在依赖关系时的await写法

//演示写法
async function f() {
    const promiseA = await fetch("http:/l.../post/1");
    const promiseB = await fetch("http: /l.../post/2");
}

/*将上面的代码写成下面的这样就行,两个fetch会并发进行(线程级别的并发估计是协程实现的)**********************************************/
async function f() {
    const promiseA = fetch("http:/l.../post/1");
    const promiseB = fetch("http: /l.../post/2");
    const [a, b] = await Promise.all([promiseA, promiseB]);
}

4,不能使用forEach或map等方法遍历执行await修饰的函数

        下面的写法不可行。原因就是尽管await会等待结果,但是由于foreach和map的特性,可能出现还没有等到结果返回,就已经进入下一个函数,而下一个函数需要上一个函数的结果。这种情况适用于上下代码存在依赖关系。解决方法就是使用传统的for循环。

js异步编程: Promise, async, await_第1张图片

        假如多个异步函数之间不存在依赖关系且需要循环,可以使用for……await来遍历执行,这种形式是并发执行这些异步函数,效率高。

js异步编程: Promise, async, await_第2张图片

5,await不能修饰普通函数和方法

        这里的普通函数指的是全局函数之类的。

你可能感兴趣的:(JavaScript,javascript,前端,es6,ecmascript)