一、单线程
单线程:只有一个线程,只能做一件事
原因:避免DOM渲染的冲突
解决方案:异步
浏览器可以渲染DOM
js可以修改DOM结构
js执行的时候,浏览器DOM渲染会暂停
两段js也不能同时执行(都修改DOM就冲突了)
webworker支持多线程,但是不能访问DOM
二、event- loop
event-loop: 事件轮询,js实现异步的具体解决方案
1、同步代码,直接执行
2、异步函数先放在异步队列中
3、待同步函数执行完毕,轮询执行异步队列的函数
$(function () {
$.ajax({
url: 'xxx',
success: function () {
console.log(0)
}
}) // 访问成功后,被加入到异步队列中(看响应速度)
setTimeout(function () {
console.log(1)
}, 100) // 100ms 之后被放入异步队列
setTimeout(function () {
console.log(2)
}) // 立即被放入异步队列
console.log(3) // 主进程
// 输出结果
// 3 2 1 0 也有可能是 3 2 0 1
})
三、jQuery的Deferred
function waitHandle() {
var dtd = $.Deferred() //创建一个deffered对象
var wait = function (dtd) { // 要求传入一个deferred对象
var task = function () {
console.log('执行完成')
dtd.resolve() // 表示异步任务已经完成
// dtd.reject() // 表示异步任务失败或出错
}
setTimeout(task, 2000)
return dtd // 要求返回deferred对象
}
// 注意,这里一定要有返回值
return wait(dtd)
}
var w = waitHandle()
w.then(function () {
console.log('ok 1')
}, function () {
console.log('error 1')
}).then(function () {
console.log('ok 2')
}, function () {
console.log('error 2')
})
var ajax = $.ajax('./data.json')
ajax.done(function () {
console.log('success1')
}).fail(function () {
console.log('error')
}).done(function () {
console.log('success2')
})
返回一个deferred对象
无法改变js异步和单线程的本质
只能从写法上杜绝callback这种形式
它是一种语法糖形式,但是解耦了代码
很好的体现:开放封闭原则(可扩展,不可修改)
// 使用jquery deferred
function waitHandle() {
var dtd = $.Deferre