您可能知道,Javascript
语言的
执行环境是一个单
线程(单线程)。
所谓单线程是指一次只能完成一个
任务。如果有多个任务,则必须排队,完成前一个任务,执行下一个任务,等等。
这种
模式的优点是实现起来相对简单,执行环境相对简单。缺点是,只要一个任务需要很长的时间,它后面的任务必须排队等,这将延迟整个项目的执行。常见的
浏览器(假死),没有
反应,往往是因为一段Javascript代码,
运行时间长(如死亡周期),因为在这个地方整个页卡,无法执行其他任务。
为了
解决这个问题,Javascript语言将任务的执行模式划分为两种
类型:
同步(异步)和异步(异步)。
是一个同步模式,一个任务
等待任务结束后,再执行
顺序执行,和任务
程序的顺序是一致的,同步;异步模式是完全不同的,每个人都有一个或多个回调
函数(回调),前一个任务结束后,在执行一个任务,但执行回调函数,后一个任务是不同的在执行任务,所以执行异步任务程序的顺序是不一致的。
异步模式是非常重要的,在浏览器端,长时间运行的
操作应该异步执行,以避免浏览器失去响应,最好的例子是ajax操作,在
服务器端,异步模式是唯一的模式,因为执行环境是单线程的。如果允许所有HTTP请求同步执行,服务器
性能就会急剧下降,并且很快就会失去响应。
本文总结了异步模式编程的4种
方法。理解它们使您能够编写更合理的结构、更好的性能和更容易
维护的Javascript程序。
一、回调函数
这是异步编程的最基本方法。
假设有两个函数,F1和F2,它们等待前者的结果。
复制代码代码如下所示:
(F1);
(F2);
如果F1是一项耗时的任务,您可以考虑重写F1并将F2作为f1的回调函数。
复制代码代码如下所示:
函数f1(回调){
setTimeout(){()函数(
f1任务代码
回调();
},1000);
}
执行代码如下所示:
复制代码代码如下所示:
f1(F2);
通过这种方式,我们将操作同步为异步操作。f1不会阻塞程序执行,这相当于首先执行程序的主要逻辑,并推迟执行耗时的操作。
回调函数的优点是简单、易于理解和部署。缺点是不利于代码读取和维护。耦合是高度耦合的,而且过程非常混乱,每个任务只能分配回调函数。
二、事件监控
另一种思维方式是使用事件驱动模式,任务的执行并不依赖于代码的顺序,而是取决于事件的发生。
以F1和F2为例。首先,F1绑定到一个事件(这里使用的jQuery的编写方法)。
复制代码代码如下所示:
f1.on('done,F2);
上面的代码行意味着在F1中完成事件时,将执行F2,然后重写F1:
复制代码代码如下所示:
函数f1(){
setTimeout(){()函数(
f1任务代码
f1.trigger('done);
},1000);
}
f1.trigger('done)表明,当执行完成后,进行事件触发立即开始执行的F2。
这种方法的优点是易于理解,可以绑定多个事件。每个事件可以指定多个回调函数,它可以解耦(脱钩),这有利于模块化。缺点是整个程序将成为事件驱动,以及运行过程中会变得非常不清楚。
三,发布/订阅
最后一节中的事件可以完全理解为
信号。
我们假设有一个信号中心。当一个任务被执行时,一个信号被发送到信号中心(发布)。其他任务可以订阅(订阅)到信号中心,以便知道何时开始执行。这称为发布订阅模式,也称为观察者模式。
有许多实现这种模式,以下是小酒吧/子本阿尔曼,这是一个jQuery
插件。
首先,F2订阅完成信号的信号中心jQuery。
复制代码代码如下所示:
jquery.subscribe(做
然后,F1改写如下:
复制代码代码如下所示:
函数f1(){
setTimeout(){()函数(
f1任务代码
JQuery.publish(做);
},1000);
}
JQuery.publish(做)意味着当F1是执行,完成信号发出的信号中心jQuery,因此引发的F2执行。
此外,F2还可以在执行完成后
取消订阅(退订)。
复制代码代码如下所示:
jquery.unsubscribe(做
这种方法的性质与事件监控类似,但显然比后者更好,因为我们可以看到多少个信号,每个信号有多少
用户,并通过查看
消息中心来监视程序的操作。
四、承诺对象
承诺对象由CommonJS
工作组提供异步编程的目的提出了一个统一的接口规范。
简单的说,每个异步任务都返回一个允诺对象,这个对象有一个允许回调函数被指定的方法:
复制代码代码如下所示:
f1()。然后(F2);
F1将重写如下(这是jQuery的实现):
复制代码代码如下所示:
函数f1(){
VaR的定义为
延期();
setTimeout(){()函数(
f1任务代码
Dfd.resolve();
},500);
返回dfd.promise;
}
这种方法的优点是回调函数成为链写,程序的流程可以清晰地看到,并且有一组匹配的方法可以实现许多强大的
功能。
例如,指定多个回调函数:
复制代码代码如下所示:
f1()。然后(F2)。然后(F3);
例如,指定
错误发生时的回调函数:
复制代码代码如下所示:
f1()。然后(F2)。失败(F3);
此外,它的优点是没有前三种方法:如果任务已经完成并添加回调函数,回调函数将立即执行,因此您不必担心缺少事件或信号,这种方法的缺点是编写和理解起来比较困难。