js基础--异步

发布日期:2019-05-26

1.关于异步的几个概念

(1)触发和执行不是一个意思

计数器的回调函数一定会在指定的delay后触发,但此时不一定立即执行,可能需要等待(等待所需的资源的释放)

(2)事件队列

onclick等由浏览器的内核DOM binding模块处理,当事件触发时,立即加入任务队列

setTimeout由timer模块进行延时处理,当时间到达时,它的回调才被加入任务队列

ajax由network模块处理,当网络请问完成时,回调才被加入任务队列

(3)setTimeoutsetInterval

setTimeout是delay一定时间后将回调加入任务队列,而setInterval是每个一定时间后将回调加入任务队列,但是如果此时任务队列里还有此回调,则会忽略此次,所以setInterval可能会出现中间某次没有执行的情况

(4)事件循环

js会创建一个类似while的循环,每次tick查看是否有待处理的事件,如果有就取出并放入主线程执行

(5)在es6,新增的任务队列,如(promise)优先级比任务队列优先级更高

2.promise

以前对于异步处理,我们都是通过回调来处理,将回调拆解成一个个的function,或者使用事件发布/监听模式等多种方式来处理较复杂的异步,

现在es6给出了新的解决方案,promise,对于不支持promise的IE11和Opera Mini,我们使用polyfill可处理es6-promise

(1) promise内部实现了resolve和reject这两个回调,通过它们可修改promise对象的状态,将异步操作的结果通过参数传递出去

new Promise((resolvereject) => { asyncfun() resolve("end") }).then(data => { console.log(data) //end})

  (2) 经常使用到的Promise.all()接收promise数组,按顺序添加进入异步队列,等所有任务结束后,结果按顺序映射到result内,返回的仍是一个数组

Promise.all([promise1promise2promise3]).then(result => { console.log(result) //[] })

  3.async await

promise解决了我们对于异步的很多麻烦,但是仍显冗余,需要.then()同时里面使用匿名函数接收结果,所有在promise基础上有了async函数,这是es2017的标准

(1)async用于声明一个函数的异步函数,它总是返回promises,无论这个函数内部return什么值

const asyncFun1 = async () => { return "str" }const asyncFun2 = async () => {return new Promise((resolvereject) => { setTimeOut(() => { resolve("str") }1000) })}  

asyncFun1内部return一个字符串,实际上会被包装成Promise.resolve("str")asyncFun2本身就返回以一个promise对象

(2)await 操作符用于等待promise或其他要等待的值,只能在async函数内使用

async () =>{let data = await new Promise((resolvereject) => {

 setTimeOut(() => { resolve("str") }1000) })

}) console.log(data) //str}

(3)多个异步处理

串行处理(等待前一个异步执行完后,发起后一个异步)

并行处理(多个异步同时发起,等待异步完成)

const seriaFn = async () => { console.time("seriaFn") console.log(await asyncFunction("str1")) console.log(await asyncFunction("str2")) console.timeEnd("seriaFn") //串行处理,耗时约2000ms /*等价于 asyncFunction("str1").then(str => { console.log(str) return asyncFunction("str2") }).then(str => { console.log(str) })*/}const parallel = async () => { console.time("parallel") const parallelOne = asyncFunction("str1") const parallelTwo = asyncFunction("str2") console.log(await parallelOne) console.log(await parallelTwo) //耗时约1000毫秒/*等价于 const [parallelOneparallelTwo] = await Promise.all([asyncFunction("str1")asyncFunction("str2")]) *//*或者Promise.all([asyncFunction()asyncFunction()]).then([result1result2] => { console.log(result1result2) })*/}

4.async模块

这是一个很实用的模块,提供了强大的函数来支持异步处理,包括async.map()等20多个功能性的方法,和async.waterfall()等异步控制的方法,具体可查看api

5.async也是html5<script>标签的一个属性,规定脚本被异步执行