首页 > 编程语言 >Javascript异步编程的4种方法

Javascript异步编程的4种方法

时间:2023-05-08 16:37:37浏览次数:54  
标签:异步 f2 编程 f1 Javascript 任务 done 执行


你可能知道,Javascript语言的执行环境是"单线程"(single thread)。

所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。

这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏 览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。可以500%提高开发效率的前端UI框架!

为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。

"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则完全 不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结 束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

"异步模式"非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。可以500%提高开发效率的前端UI框架!

本文总结了"异步模式"编程的4种方法,理解它们可以让你写出结构更合理、性能更出色、维护更方便的Javascript程序。

一、回调函数

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

假定有两个函数f1和f2,后者等待前者的执行结果。


  1. f1();  
  2.     
  3. f2();  

 

如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。


  1. function f1(callback){  
  2.     
  3.   setTimeout(function () {  
  4.     
  5.     // f1的任务代码  
  6.     
  7.     callback();  
  8.     
  9. 1000);  
  10.     
  11. }  



 

执行代码就变成下面这样:


  1. f1(f2);  


 

采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。

回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。可以500%提高开发效率的前端UI框架!

二、事件监听

另一种思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。

还是以f1和f2为例。首先,为f1绑定一个事件(这里采用的jQuery的写法)。




  1. f1.on('done', f2);  



 

上面这行代码的意思是,当f1发生done事件,就执行f2。然后,对f1进行改写:




  1. function f1(){  
  2.     
  3.   setTimeout(function () {  
  4.     
  5.     // f1的任务代码  
  6.     
  7. 'done');  
  8.     
  9. 1000);  
  10.     
  11. }  



 

f1.trigger('done')表示,执行完成后,立即触发done事件,从而开始执行f2。

这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合"(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。

三、发布/订阅

上一节的"事件",完全可以理解成"信号"。

我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe pattern),又称"观察者模式"(observer pattern)。

这个模式有多种实现,下面采用的是Ben Alman的Tiny Pub/Sub,这是jQuery的一个插件。

首先,f2向"信号中心"jQuery订阅"done"信号。 可以500%提高开发效率的前端UI框架!




  1. jQuery.subscribe("done", f2);  



 

然后,f1进行如下改写:




  1. function f1(){  
  2.     
  3.   setTimeout(function () {  
  4.     
  5.     // f1的任务代码  
  6.     
  7. "done");  
  8.     
  9. 1000);  
  10.     
  11. }  



 

jQuery.publish("done")的意思是,f1执行完成后,向"信号中心"jQuery发布"done"信号,从而引发f2的执行。

此外,f2完成执行后,也可以取消订阅(unsubscribe)。




  1. jQuery.unsubscribe("done", f2);  



 

这种方法的性质与"事件监听"类似,但是明显优于后者。因为我们可以通过查看"消息中心",了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。

四、Promises对象

Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。

简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:




  1. f1().then(f2);  



 

f1要进行如下改写(这里使用的是jQuery的实现): 可以500%提高开发效率的前端UI框架!




  1. function f1(){  
  2.     
  3.   var dfd = $.Deferred();  
  4.     
  5.   setTimeout(function () {  
  6.     
  7.     // f1的任务代码  
  8.     
  9.     dfd.resolve();  
  10.     
  11. 500);  
  12.     
  13.   return dfd.promise;  
  14.     
  15. }  



 

这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。

比如,指定多个回调函数:




  1. f1().then(f2).then(f3);  



 

再比如,指定发生错误时的回调函数: 可以500%提高开发效率的前端UI框架!




  1. f1().then(f2).fail(f3);  



 

而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难

本文引用:http://www.iteye.com/topic/1135798


标签:异步,f2,编程,f1,Javascript,任务,done,执行
From: https://blog.51cto.com/u_16092550/6254918

相关文章

  • 【编程入门】应用市场(NodeJS版)
    背景前面已输出多个系列:《十余种编程语言做个计算器》《十余种编程语言写2048小游戏》《17种编程语言+10种排序算法》《十余种编程语言写博客系统》《十余种编程语言写云笔记》《N种编程语言做个记事本》目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。让想学......
  • JavaScript: XMLHTTPRequest
     XMLHttpRequest(javascript.info)<body><script>//CreateanewXMLHTTPRequestobjectletxhr=newXMLHttpRequest()xhr.timeout=5000//timeoutinmsleturl=newURL('https://cursive.winch.io/......
  • Python 和 JavaScript 的区别是什么?
    Python和JavaScript是两门非常流行的编程语言,它们各自有着独特的特点和应用场景。Python和JavaScript是两种不同的编程语言,它们的设计目标和应用场景有所不同。Python是一种多用途、高级、解释型的编程语言,可用于开发各种应用程序,包括Web开发、数据分析、人工智能、科学计算......
  • JavaScript原生兼容大全-持续更新
    JavaScript兼容-持续更新1.css非行内样式操作//currentStyle用于IE低版本getComputed用于主流浏览器//element目标元素attribute目标属性functiongetStyle(element,attribute){returnelement.currentStyle?element.currentStyle(attribute):getComputed(el......
  • JavaScript fromCharCode() 方法
    fromCharCode()方法返回指定的Unicode编码对应的字符。语法格式:String.fromCharCode(n1,n2,...)参数:n1,n1,..表示指定的Unicode编码。示例:(1)返回指定Unicode编码的字符:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8">&......
  • c#中使用 async 和 await 的异步编程
    什么是异步编程异步编程是对线程的一种应用方式。类似于人跑步时戴着耳机听歌,这两个行为可以同时进行,而不是先跑完步再听歌。异步编程就是同一时间做多件事,通常异步编程就是在继续运行原有逻辑的同时,把耗时的操作放进一个单独的线程中进行并行处理,以重复利用CPU资源以及节省总的......
  • 网络编程
    一.楔子你现在已经学会了写python代码,假如你写了两个python文件a.py和b.py,分别去运行,你就会发现,这两个python的文件分别运行的很好。但是如果这两个程序之间想要传递一个数据,你要怎么做呢?这个问题以你现在的知识就可以解决了,我们可以创建一个文件,把a.py想要传递的内容写到文件中......
  • 面向对象编程
    对象的概念”面向对象“的核心是“对象”二字,而对象的精髓在于“整合“,什么意思?所有的程序都是由”数据”与“功能“组成,因而编写程序的本质就是定义出一系列的数据,然后定义出一系列的功能来对数据进行操作。在学习”对象“之前,程序中的数据与功能是分离开的,如下#数据:name、ag......
  • 2023.5.7编程一小时打卡
    一、问题描述:编写程序提示用户输入一个班级中的学生人数n,再依次提示用户输入n个人在课程A中的考试成绩,然后计算出平均成绩显示出来。二、解题思路:首先,定义一个vector类型的成员,通过用户输入的人数进行对vector的数据添加,最后进行加和求其平均值。 三、代码实现:1#include......
  • NOI / 1.8编程基础之多维数组
    13:图像模糊处理 1.描述给定n行m列的图像各像素点的灰度值,要求用如下方法对其进行模糊化处理:1.四周最外侧的像素点灰度值不变;2.中间各像素点新灰度值为该像素点及其上下左右相邻四个像素点原灰度值的平均(舍入到最接近的整数)。2.输入第一行包含两个整数n和m,表示图像包含......