李瑞云
2017.12.05
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。于是就有一个概念,任务队列。
同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。最基础的异步是setTimeout和setInterval函数
众所周知,js中的同步异步常常是导致BUG出现的根源,这里的同步是指js是按照从上向下的顺序执行的,如果不出现异步操作代码将从头运行到尾
这会带来严重的性能问题,试想ajax等待结果返回浏览器再进行操作,那会出现什么结果。。
所以再各同步环境中,提供了不同的方式将同步做成异步,以提高性能。但这也带来了问题。。
OK,这里我们说说回调函数,什么是回调函数,说白了就是一个参数,这个参数的类型是function
回调函数在js中的使用是非常广泛的, 比如,将函数传入函数,然后在函数中调用函数, 然后再传入函数,再在函数中调用函数--有没有一点像绕口令
确实很绕,我们来看一段代码。
// 这是一个常见的ajax函数
$.ajax(url, function() {
// do something
});
// 当我们要回调的时候,我们怎么办?
var callbackFn = function callbackFn() {
// hello, i am a callback function
}
$.ajax(url, function() {
// do something
callbackFn();
});// 当回调函数又需要回调的时候呢?
var cbFn = function cbFn() {
// hi, i am callback function too
}
var callbackFn = function callbackFn(cbFn) {
// hi, i am callback function
cbFn();
}
$.ajax(url, function() {
// do something
callbackFn();
}
// OK, now 有没有一点身处地狱的感觉
// 如果没有,请增加回调的层数,直到有感觉~~more
为了返回人间,逃出地狱
在jq 1.5中,增加了一个deferred对象,这个对象能够帮我们重回人间
// 链式操作
$.ajax(url, data)
.done(function() {
// do when success
}).fail(function() {
// do when fail
}).always(function() {
// always do
});
deferred对象的一大好处,就是它允许你自由添加多个回调函数。它们按照添加顺序执行。
在ES6中,Promise终于成为了原生对象,可以直接使用。console.dir(Promise)
Promise构造函数接受一个函数作为参数,
该函数的两个参数分别是resolve方法和reject方法。
如果异步操作成功,则用resolve方法将Promise对象的状态变为“成功”(即从pending变为resolved);
如果异步操作失败,则用reject方法将状态变为“失败”(即从pending变为rejected)。
是不是有点抽象?
OK,我们来看看状态机
promise-ex1
Text
var promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
参考文献