js12异步编程1

异步

什么是异步

首先要了解的是:JavaScript语言的执行环境是单线程(this thread,指一次只能完成一件任务,如果有多个任务,就必须排队,前面一个任务执行完成,再执行后面一个任务,以此类推)
这种模式的好处就是实现起来比较简单,执行环境相对单纯,坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行,常见的浏览器无响应(假死),往往就是因为某一段JavaScript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行,一个操作耗时比较多的时候,尤其是跟后端有关的时候,后端返回一个值之后,我再去进行下一个请求,所以用异步近似于同时发出,不是同时发出,是按顺序发出的,但是不用等上一次请求完成后再进行下一次请求。
js整个执行环境都是单线程的,我们只不过是调整排队顺序。
为了解决这个问题,JavaScript将任务的执行模式分为两种:同步(Synchronous)和异步(Asynchronous)

同步任务(synchronous):就是后一个任务等待前一个任务完全结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的
异步任务(asynchronous):每一个任务有一个或多个回调函数(callback)(回调函数是干嘛用的,回调当收到了某些值或某些情况的时候,再去执行回调函数,比如一个请求,返回后端API,再执行回调函数处理这个API),前一个任务不是完全结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的,在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,异步模式甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降



Event Loop事件循环机制
浏览器或Node的一种解决JavaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理
event loop它的执行顺序为:
一开始整个脚本作为一个宏任务执行
执行过程中同步代码直接执行,宏任务进入宏任务队列,微任务进入微任务队列
当前宏任务执行完出队,检查微任务列表,有则依次执行,直到全部执行完
执行浏览器的UI渲染工作
检查是否有web worker任务,有则执行
执行完本轮的宏任务,回到2,依次循环,直到宏任务和微任务队列都为空
<script type="module" src="chrome://resources/cr_elements/cr_toggle/cr_toggle.js" async></script>,script作为一个标签作为函数的入口,script就是一个宏任务当它接受到这个宏任务的时候再去执行里面的js代码。


什么是宏任务队列,微任务队列

宏任务队列,也叫宏队列:script标签,setTimeout,setInterval,setImmediate,I/O(上传文件,点击等操作的时候。),UI rendering

微任务队列,也叫微队列:MutationObserver,Promise,then()或catch(),Pronise为基础开发的其他技术,比如fetch API,v8垃圾回收过程,async,Node独有的process.nextTick等

对于我们chrome里的js而言,需要重点关注的时setTimeout,setIneterval,Promise.then,async


在所有的任务开始的时候,由于宏任务中包括了script,所以浏览器会先执行一个宏任务,再这个过程中你看到的延迟任务(列如setTimeout)将被放到下一轮宏任务中来执行。



promise的状态

1.初始态pending

创建Promise对象时,且没有调用resolve或者时reject方法,相当于时初始状态。这个初始状态会随着你调用resolve,或者时reject函数而切换到另一种状态。
2.成功态【解决态】resolved--也叫fulfilled
要实现从pending到resolved的转变,需要在创建Promise对象时,在函数体中调用了resolve方法(即第一个参数)

3.失败态【拒绝态】rejected
rejected。拒绝,失败。表示这个承诺没有做到,失败了。要实现从pending到rejected的转换,只需要在创建Promise对象时,调用reject函数

首先 promise是一个构造函数,使用的时候需要配合new来使用。 Promise() 直接调用会报错 new Promise() 也会报错: Promise resolver undefined is not a function 所以正常的流程应该是这样滴: new Promise(function(){console.log(arguments)}) 需要传入一个函数参数,作为Promise的回调函数。 实际上是这样的: var callback = function(resolve, reject){} const promise1 = new Promise(callback) console.log(promise1)  

promise a+规范英文版

promise a+规范中文版



从上至下,先遇到new Promise,执行其中的同步代码1
 再遇到resolve('success'), 将promise的状态改为了resolved并且将值保存下来
 继续执行同步代码2
 跳出promise,往下执行,碰到promise.then这个微任务,将其加入微任务队列【注意,这里实际上发生的过程在看到.then的一瞬间还会创建promis, promise.then是const promise = new Promise((resolve, reject)这个创建的promise(成功态),当遇到promise.then的时候会在前面自动创建一个promise_then(pending),先放到微队列中等待执行,注意是没有执行,继续会执行同步操作,promise.then(() => {console.log(3)});当这个函数执行完没有报错的时候,就会把promise_then改成成功态,如果报错了设置成失败态】
 执行同步代码4
 执行同步代码promise,打印promise的状态
/ 本轮宏任务队列全部执行完毕,检查微任务队列,发现promise.then这个微任务且状态为resolved,执行它。

const promise = new Promise((resolve, reject) => {
console.log(1);
reject('failed')
console.log(2);
});
promise.then(() => {
console.log(3);
});
console.log(4);

promise.then(() => {
console.log(3);
});该代码不会执行,只有当const promise = new Promise((resolve, reject) => {console.log(1);
reject('failed')console.log(2);});这段代码把promise状态设置成成功态的时候才会放到微队列中去执行的。


 

 问题1:promise.then的回调函数里面,是否有参数?
问题2:promise.then方法是否有返回值?

const then_callback = function(){console.log(arguments)}
const promise = new Promise((resolve, reject) => {
resolve('success')
});
const result = promise.then(then_callback);
console.log(result);

结论,当一个已完成的“F”状态的Promise遇到一个 then方法,一定瞬间产生一个新的 Promise ,状态为P

const promise1 = new Promise((resolve, reject) => {//自动执行回调函数的代码,是同步的
console.log('promise1')
resolve('resolve1')//修改promise1的状态
})
const promise2 = promise1.then(res => {//当一瞬间调用promise1.then的时候,不管后面是什么东西都会形成一个新的promise状态,其中promise2中的回调函数当promise1是成功态的时候才会把回调函数放到微任务队列中。
console.log(res)
})
console.log('1', promise1);
console.log('2', promise2);
// 从上至下,先遇到new Promise,执行该构造函数中的代码promise1
// 碰到resolve函数, 将promise1的状态改变为resolved, 并将结果保存下来
// 碰到promise1.then这个微任务,将它放入微任务队列【只要遇到then方法,一定产生一个新的promise】
// promise2是一个新的状态为pending的Promise
// 执行同步代码1, 同时打印出promise1的状态是resolved
// 执行同步代码2,同时打印出promise2的状态是pending
// 宏任务执行完毕,查找微任务队列,发现promise1.then这个微任务且状态为resolved,执行它。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值