分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

JS高级-异步

发布时间:2023-09-06 02:35责任编辑:白小东关键词:暂无标签

单线程

  只有一个线程,同一时间只能做一件事

  原因:避免DOM渲染的冲突

    浏览器需要渲染DOM

    JS可以修改DOM结果

    JS执行的时候,浏览器DOM渲染会暂停

    两段JS也不能同时执行(修改DOM就冲突)

    webworker支持多线程,但是不能访问DOM,本质JS还是单线程

  解决方案:异步

case1

{ ???var i, sum = 0 ???for(i = 0; i < 100000000; i++) { ???????sum += i ???} ???console.log(sum)}

case2

{ ???console.log(1) ???alert(‘a‘) ???console.log(2)}

分析:JS执行阻塞DOM渲染,出现卡顿。因为js是单线程

case3

{ ???console.log(100) ???setTimeout(function(){ ???????console.log(200) ???},100) ???console.log(300)}

分析:JS是单线程的,第一行打印100,第二行setTimeout是异步,暂时不执行,先往下执行,第三行打印300,代码结束。然后发现setTimout没执行,那么打印200。

event-loop

  事件轮询,JS实现异步的具体解决方案

  同步代码,直接执行

  异步函数先放在异步队列中

  待同步函数执行完毕,轮询执行异步队列的函数

case1

{ ???console.log(100) ???setTimeout(function(){ ???????console.log(200) ???},100) ???console.log(300)}

分析:同步代码,直接执行,第一行和第三行是同步代码,直接打印100和300,第二行是异步代码,先放入异步队列。同步代码执行完毕,这时候查看异步队列,执行setTimeout打印200

case2

{ ???console.log(100) ???setTimeout(function(){ ???????console.log(200) ???},100) ???setTimeout(function(){ ???????console.log(300) ???}) ???console.log(400)}

分析:同步代码直接执行,第一行和第四行直接执行,打印100和400。

   同步代码执行完毕,查看异步队列。这时候有2个setTimeout函数,第三行会直接放入异步队列中,那么打印300。

   而第二行100ms之后才被放入异步队列中,打印200

case3

{ ???$.ajax({ ???????url:‘‘, ???????success:function(result){ ???????????console.log(‘a‘) ???????} ???}) ???setTimeout(function(){ ???????console.log(‘b‘) ???},100) ???setTimeout(function(){ ???????console.log(‘c‘) ???}) ???console.log(‘d‘)}

结果: d c a b或者 d c b a

jQuery的Deferred

  dtd.resolve/dtd.reject

  dtd.then/dtd.done/dtd/fail

case1

function waitHandle() { ???var dtd = $.Deferred() ???!function(dtd){ ???????var task = function() { ???????????console.log(‘执行完毕‘) ???????????dtd.resolve() ???????} ???????setTimeout(task, 2000) ???}(dtd) ???return dtd}waitHandle() ???.then(function(){ ???????console.log(‘success‘) ???})

case2

function waitHandle() { ???var dtd = $.Deferred() ???!function(dtd){ ???????var task = function() { ???????????console.log(‘执行完毕‘) ???????????dtd.resolve() ???????} ???????setTimeout(task, 2000) ???}(dtd) ???return dtd.promise()}var w = waitHandle() ???$.when(w).then(function(){ ???????console.log(‘success‘) ???})

注意:这2个case不同之处一个case是返回dtd还有一个返回dtd.promise()对象。

   第一个case w.reject()不会报错,但是会出现代码混乱

   第二个case w.reject()会报错,无法干预代码

Promise

  回顾下语法

case

{ ???function loadImg(src){ ???????return new Promise((resolve, reject)=>{ ???????????let img = document.createElement(‘img‘) ???????????img.onload = () => resolve(img) ???????????img.onerror = () => reject() ???????????img.src = src ???????}) ???} ???const src = ‘https://....jpeg‘ ???var res = loadImg(src) ???res.then(img => { ???????console.log(img) ???}, () => { ???????console.log(‘fail‘) ???})}

 异常捕获

  使用catch统一捕获异常

case

{ ???function loadImg(src){ ???????return new Promise((resolve, reject)=>{ ???????????let img = document.createElement(‘img‘) ???????????img.onload = () => resolve(img) ???????????img.onerror = () => reject(‘异常‘) ???????????img.src = src ???????}) ???} ???const src = ‘https://....jpeg‘ ???var res = loadImg(src) ???res.then(img => { ???????console.log(img) ???}).catch(e => { ???????console.log(e) ???})}

多个串联

  链式操作部分代码

const res = loadImg(src) ???const res2 = loadImg(src2) ???res.then(() => { ???????console.log(‘one‘) ???????return res2 ???}).then(() => { ???????console.log(‘two‘) ???}).catch(e => { ???????console.log(e) ???})

Promise.all和Promise.race 

  Promise.all接收一个promise对象的数组,待全部完成之后,统一执行then

  Promise.race接收一个promise对象的数组,只要一个完成,就执行then

async/await

  直接只用同步写法

case

{ ???function loadImg(src){ ???????return new Promise((resolve, reject)=>{ ???????????let img = document.createElement(‘img‘) ???????????img.onload = () => resolve(img) ???????????img.onerror = () => reject(‘异常‘) ???????????img.src = src ???????}) ???} ???const src = ‘https://....jpeg‘ ???const src2 = ‘https://...jpg‘ ???????async function load() { ???????const res = await loadImg(src) ???????console.log(res) ???????const res2 = await loadImg(src2) ???????console.log(res2) ???} ???load()}

虽然是同步写法,但是使用了Promise,并没有改变JS时单线程,异步的本质

JS高级-异步

原文地址:https://www.cnblogs.com/sonwrain/p/10540416.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved