总体介绍
js 的执行环境是单线程
js 的执行模式分同步,异步
所以 js 的异步非常重要
事实上,程序中现在运行的部分和将来运行的部分之间的关系就是异步编程的核心。
calback
同步
f1()
f2()
异步
function f1(callback){
setTimeout(function () {
// f1的任务代码
callback();
}, 1000);
}
f1(f2);
异步回调是指回调函数在主函数之外执行,一般有两种方式:
- 第一种是把异步函数做成一个任务,添加到信息队列尾部;
- 第二种是把异步函数添加到微任务队列中,这样就可以在当前任务的末尾处执行微任务了。
f1不会堵塞程序运行
优点: 简单
缺点: 耦合,回调地狱
实例:多个脚本顺序加载完执行
function laodScript(src,cb){
let script = document.createElement('script')
script.src = src
script.onload = () => { callback(src) }
document.head.append(script)
}
function test (name) {
console.log(name)
}
loadScript('./1.js',function (script) {
loadScript('./2.js',function (script) {
loadScript('./3.js',function (script) {
)}
)}
)}
事件驱动模式
注册监听,处理监听
f1.on('done', f2);
function f1(){
setTimeout(function () {
// f1的任务代码
f1.trigger('done');
}, 1000);
}
f1.trigger(‘done’)表示,执行完成后,立即触发done事件,从而开始执行f2
手动 trigger 的时候把这个事件
优点:去耦合
缺点:整个程序都要变成事件驱动型,运行流程会变得很不清晰。
发布/订阅(观察者模式)
function f2 () {
// 执行f2任务
// 取消订阅
jQuery.unsubscribe("done", f2);
}
jQuery.subscribe("done", f2);
function f1(){
setTimeout(function () {
// f1的任务代码
jQuery.publish("done");
}, 1000);
}
我们可以通过查看”消息中心”,了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。
有限状态机和 promise
有限状态机
有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物。
js 的promise 是用状态机实现的
有限状态机提供了更好的办法:把异步操作与对象的状态改变挂钩,当异步操作结束的时候,发生相应的状态改变,由此再触发其他操作。这要比回调函数、事件监听、发布/订阅等解决方案,在逻辑上更合理,更易于降低代码的复杂度。
状态总数(state)是有限的。
任一时刻,只处在一种状态之中。
* 某种条件下,会从一种状态转变(transition)到另一种状态。
它对JavaScript的意义在于,很多对象可以写成有限状态机。
var menu = {
// 当前状态
currentState: 'hide',
// 绑定事件
initialize: function() {
var self = this;
self.on("hover", self.transition);
},
// 状态转换
transition: function(event){
switch(this.currentState) {
case "hide":
this.currentState = 'show';
doSomething();
break;
case "show":
this.currentState = 'hide';
doSomething();
break;
default:
console.log('Invalid State!');
break;
}
}
};
生活中的例子是红绿灯
构成一个状态机的最简单的几个因素(这里以红绿灯作为例子):
- 状态集:红、黄、绿;
- 初始状态:红绿灯的启动状态;
- 状态转移函数:延时或者动态调度;
- 最终状态:红绿灯关闭的状态,当然也可能不存在;
todo: promise的实现
从Promise的实现来看有限状态机