Javascript中异步编程的4种方法

正如您所知道的,Javascript语言的执行环境是单线程。
所谓的单线程是指一次只能完成一个任务。如果有多个任务,则必须排队,完成前一个任务,执行下一个任务,等等。
这种模式的优点是实现起来相对简单,执行环境相对简单。缺点是,只要一个任务需要很长的时间,它后面的任务必须排队等,这将延迟整个项目的执行。常见的浏览器(假死),没有反应,往往是因为一段Javascript代码,运行时间长(如死亡周期),因为在这个地方整个页卡,无法执行其他任务。
为了解决这个问题,Javascript语言将任务的执行模式划分为两种类型:同步(异步)和异步(异步)。
同步模式是一种任务等待任务结束前,然后执行顺序执行,和任务程序的顺序是一致的,同步;异步模式是完全不同的,每个人都有一个或多个回调函数(回调),前一个任务结束,不后一个任务的执行,但执行回调函数,后一个任务是不同的在执行任务,所以执行异步任务程序的顺序是不一致的。
异步模式非常重要,在浏览器端,长时间运行的操作应该异步执行,以避免浏览器失去响应,最好的例子是Ajax操作,在服务器端,异步模式是唯一的模式,因为执行环境是单线程的。如果允许所有HTTP请求同步执行,服务器性能就会急剧下降,并且很快就会失去响应。
一、回调函数

这是异步编程的最基本方法。

假设有两个函数,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);
此外,它的优点是没有前三种方法:如果任务已经完成并添加回调函数,回调函数将立即执行,因此您不必担心缺少事件或信号,这种方法的缺点是编写和理解起来比较困难。