1、什么是单线程,和异步有什么关系
单线程:同一时间,只能做一件事;
js中单线程的原因:避免DOM渲染的冲突。
js执行和DOM渲染是共用一个线程的:两段js不能同时执行,js执行的时候DOM渲染会暂停;
单线程的解决方案–异步。
在js的世界中,所有的代码都是单线程执行的,由于这个“缺陷”,导致js所有网络操作,浏览器事件都必须是异步执行。
异步函数:setTimeout /ajax/setinterval/promise
2、异步的实现方式: 事件轮询(event-loop)
同步代码直接执行,同步函数放在主进程中,会立即执行,异步函数放在异步队列中。同步代码(主进程中的代码)执行完后js引擎会不断监视异步队列中是否有函数,若有会立即把异步队列中的函数放到主进程中执行,执行完后,js引擎再次到异步队列中查找异步函数并放到主进程执行,如此循环,称作事件轮询。
setTimeout(function(){ //100ms后会将此函数放在异步队列中
console.log(1);
},100)
3、解决异步的方案
1)promise:promise的基本使用和原理
三种状态:pending fulfiled rejected,处理状态是:pending.状态变化:pending->fulfiled或者pending->rejected;
promise最大的好处是在异步的执行流程中,吧执行代码和处理结果的代码清晰地分离开,下面写个Pomise例子:
function loadImg(src){
const promise = new Promise(function(resovle,reject){
var img = document.createElement('img');
img.onload = function(){
resolve(img);
}
img.onerror = function() {
reject();
}
img.src = src;
})
return promise ;
}
var result = loadImg(src);
result.then(function(img){
console.log(img.width);
},function(){
console.log('failed');
}).then((function(img){
console.log(img.height);
})
var r1 = loadimg(src);
var r2 = loadiimg(src);
r1.then(function(img){
console.log(‘第一张图片加载完成’);
rturn r1;
}).then(function(img){
console.log(‘第二张图片加载完成’);
})
all和race
promise的详细介绍:廖雪峰的官网
promise原理
其实,promise就是三个状态。利用观察者模式,只需要通过特定书写方式注册对应状态的事件处理函数,然后更新状态,调用注册过的处理函数即可。
这个特定方式就是then,done,fail,always…等方法,更新状态就是resolve、reject方法。 摘自promise原理浅析
2) Async Awiat(es7)
async 函数返回的是一个promise 对象;关键字await 表示等一下,代码就暂停到这里,不再向下执行了,它等什么呢?等后面的promise对象执行完毕,然后拿到promise resolve 的值并进行返回,返回值拿到之后,它继续向下执行。特点:完全是同步的写法,再也没有回调函数。
写个例子:
function yibuFn (num){
//返回promise 对象
return new Promise(function(resolve,reject){
setTimeout(function(){
if(num>30){
resolve(num*2);
}else{
reject(num+1);
}
},1000)
})
}
async function test(){
let result1 = await yibuFn(50);
console.log("result1:",result1);
let result2 = await yibuFn(20);
console.log("result2:",result2 );
}

[详细介绍见博客](https://www.cnblogs.com/SamWeb/p/8417940.html)
3)JQuery的Defferred(JQuery1.5以后)
function waitHandle(){
var dtd = $.Deferred();
var wait = function (dtd){
var task = function(){
console.log("执行完成");
dtd.resolve();//成功
// dtd.reject();//失败
}
setTimeout(task,1000);
return dtd.promise(); //wait返回
}
return wait(dtd);
}
var w = waitHandle(); //promise对象
$.when(w).then(function(){
console.log(‘ok1’);
},function(){
console.log(‘error 1’);
});
在写法上杜绝了callback这种形式
一种语法糖,但是解耦了代码
很好的体现:开放封闭原则