加入收藏 | 设为首页 |

anggame安博电竞app-【前端面试题】异步和单线程

海外新闻 时间: 浏览:151 次

异步

什么是单线程,和异步有什么关系

  • 单线程:只需一个线程,同一时间只能做一件事,两段JS不能一起履行
  • 原因:防止DOM烘托的抵触
  • 处理计划:异步

为什么js只需一个线程:防止DOM烘托抵触

  • 浏览器需求烘托DOM
  • JS能够修正DOM结构
  • JS履行的时分,浏览器DOM烘托会暂停
  • 两头JS也不能一起履行(都修正DOM就抵触了)
  • webworker支撑多线程,可是不能拜访DOM

什么是event-loop

  • 事情轮询,JS完结异步的详细处理计划
  • 同步代码,直接履行(主线程)
  • 异步函数先放在异步行列中(使命行列)
  • 待同步函数履行结束,轮询履行异步行列的函数
setTimeout(function(){
console.log(1);
},100); //100ms之后才放入异步行列中,现在异步行列是空的
setTimeout(function(){
console.log(2); //直接放入异步行列
})
console.log(3) //直接履行
//履行3之后,异步行列中只需2,把2拿到主线程履行
//2履行完之后,异步行列中并没有使命,所以一向轮询异步行列
//直到100ms之后1放入异步行列,将1拿到主线程中履行
仿制代码
$.ajax({
url:'./data.json',
success:function(){ //网络恳求成功就把success放入异步行列
console.log('a');
}
})
setTimeout(function(){
console.log('b')
},100)
setTimeout(function(){
console.log('c');
})
console.log('d')
//打印成果:
//d //d
//c //c
//a //b
//b //a
//实在环境不会呈现dacb
仿制代码

处理计划存在的问题

  • 问题一:没依照书写办法履行,可读性差
  • 问题二:callback中不容易模块化

是否用过jQuery的Deferred

  • jQuery1.5的改动
  • 运用jQuery Deferred
  • 开始引进Promise概念

jQuery1.5之前

var ajax = $.ajax({
url:'./data.json',
success:function(){
console.log('success1');
console.log('success2');
console.log('success3');
},
error:function(){
console.log('error');
}
})
console.log(ajax); //回来一个XHR目标
仿制代码

jQuery1.5之后

第一种写法:

var ajax = $.ajax('./data.json');
ajax.done(function(){
console.log('success1')
})
.fai(function(){
console.log('fail')
})
.done(function(){
console.log('success2');
})
console.log(ajax); //deferred目标
仿制代码

第二种写法:

var ajax = $.ajax('./data.json');
ajax.then(function(){
console.log('success1')
},function(){
console.log('error1');
})
.then(function(){
console.log('success2');
},function(){
console.log('error');
})
仿制代码
  • 无法改动JS异步和单线程的实质
  • 只能从写法上根绝callback这种方式
  • 它是一种语法糖,可是解耦了代码
  • 很好的提现:敞开关闭准则(对扩展敞开对修正关闭)

运用jQuery Deferred

给出一段十分简略的代码,运用setTimeout函数

var wait = function(){
var task = function(){
console.log('履行完结');
}
setTimeout(task,2000)
}
wait();
仿制代码

新增需求:要在履行完结之后进行某些特别杂乱的操作,代码可能会许多,并且分好几步

function waitHandle(){
var dtd = $.Deferred(); //创立一个deferred目标

var wait = function(dtd){ // 要求传入一个deferred目标
var task = function(){
console.log("履行完结");
dtd.resolve(); //表明异步使命已完结
//dtd.reject() // 表明异步使命失利或许犯错
};
setTimeout(task,2000);
return dtd;
}
//留意,这儿现已要有回来值
return wait(dtd);
}
//运用
var w = waithandle()
w.then(function(){
console.log('ok1');
},function(){
console.log('err2');
})
.then(function(){
console.log('ok2');
},function(){
console.log('err2');
})
//还有w.wait w.anggame安博电竞app-【前端面试题】异步和单线程fail
仿制代码

总结:dtd的API可分红两类,意图不同

  • 第一类:dtd.resolve 、 dtd.reject
  • 第二类:dtd.then、dtd.done、dtd.fail
  • 这两类应该分隔,不然结果严重! 能够在上面代码中最终履行dtd.reject()试一下结果

运用dtd.promise()

function waitHandle(){
var dtd = $.Deferred();
var wait = function(){
var task = function(){
console.log('履行完结');
dtd.resolve();
}
seanggame安博电竞app-【前端面试题】异步和单线程tTimeout(task,2000)
return dtd.promise(); //留意这儿回来的是promise,而不是直接回来deferred目标
}
return wait(dtd)
}
var w = waitHandle(); //promise目标
$.when(w).then(function(){
console.log('ok1');
},function(){
console.log('err1');
})
//w.reject() //w.reject is not a function
仿制代码

监听式调用:只能被迫监听,不能干涉promise的成功和失利

  • 能够jQuery1.5对ajax的改动举例
  • 阐明怎么简略的封装、运用deferred
  • 阐明promise和Defrred的差异

要想深化了解它,就需求知道它的宿世此生

Promise的根本运用和原理

根本语法

fucntion loadImg() {
var promise = new Promise(function(resolve,reject) {
var img = document.getElementById("img")
img.onload = function(){
resolve(img)
}
img.onerror = function(){
reject()
}
})
return promise
}
var src = "anggame安博电竞app-【前端面试题】异步和单线程"
var result = loadImg(src)
result.then(function() {
console.log(1, img.width)
return img
}, fucntion() {
console.log('error 1')
}).then(function(img) {
console.log(1, img.width)
})
仿制代码

反常捕获

规则

  • then只承受一个函数(只承受一个成功的回调函数),最终一致用catch捕获反常

两种反常状况:

  • 程序逻辑反常
  • 事务之内,reject()等状况

处理计划 在reject("图片途径过错")中把信息传出去,能够经过'.catch()'捕获

var src = ""
var result = loadImg(src)
result.then(function() {
console.log(1, img.width)
return img
}).then(function(img) {
console.log(1, img.width)
}).catch(function(ex) {
//最终一致捕获反常
console.log(ex)
})
仿制代码

多个串联

var scr1 = 'https://www.imooc.com/static/img/index/logo_new.png';
var result1 = loadImg(src1);
var src2 = 'https://www.imooc.com/static/img/index/logo_new1.png';
var result2 = loadImg(src2);
result1.then(function(img1) {
console.log('第一个图片加载完结', img1.width);
return result2; 九眼桥事件//重要
}).then(function(img2) {
console.log('第二个图片加载完结', img2.width);
}).catch(function(ex) {
console.log(ex);
})
仿制代码

Promise.all和Promise.race

  • Promisanggame安博电竞app-【前端面试题】异步和单线程e.all接纳一个promise目标的数组
  • 待悉数完结后,一致履行success
Promise.all([result1, result2]).then(datas => {
//接纳到的datas是一个数组,顺次包括了多个promise回来的内容
console.log(datas[0]);
console.log(datas[1]);
})
仿制代码
  • Promise.race接纳一个包括多个promise目标的数组
  • 只需有一个完结,就履行success
Promise.race([result1, result2]).then(data => {
//data即最早履行完结的promise的回来值
console.log(data);
})
仿制代码

Promise规范

  • 状况
  • 三种状况:pending,fulfilled,rejected初始状况:pending
  • pending变为fulfilled,或许pending变为rejected
  • 状况改动不可逆
  • then
  • promise有必要完结then这个办法
  • then()有必要接纳两个函数作为规范
  • then回来的有必要是一个promise实例

没有return便是默许回来的result

Promise总结

  • 根本语法
  • 怎么反常捕获(Error和reject)
  • 多个串联-链式履行的优点
  • Promise.all和Promise.race
  • Promise规范 - 状况改动、then函数

介绍一下async/await(和Promise的差异、联络)

es7提案中,用的比较多,babel也已支撑

koa结构 async/await替换generator

处理的是异步履行和编写逻辑

then仅仅将callback拆分了

var w = watiHandle()
w.then(function(){...},function(){...})
.then(function(){...},function(){...})
仿制代码

async/await是最直接的同步写法

const load = async function(){
const result1 = await loadImg(src1)
console.log(result1)
const result2 = await loadImg(src2)
console.log(result2)
}
load()
仿制代码

用法

  • 运用await,函数后边有必anggame安博电竞app-【前端面试题】异步和单线程要用async标识
  • await后边跟的是一个Promise实例
  • 需求balbel-polyfill(兼容)

特色

  • 运用了Promise,并没有和Promise抵触
  • 完全是同步的写法,再也没有回调函数
  • 可是:改动不了JS单线程、异步的实质

总结一下当时JS异步的计划

  • jQuery Defered
  • promise
  • async/await
  • generator(能处理异步并不是为了处理异步)

原文链接:https://juejin.im/post/5c1cd35c6fb9a049aa6f0f69

假如你喜欢我的共享,那就点一下重视鼓舞一下哈