广告
返回顶部
首页 > 资讯 > 前端开发 > VUE >Javascript异步编程简介
  • 750
分享到

Javascript异步编程简介

2024-04-02 19:04:59 750人浏览 薄情痞子
摘要

这篇文章主要介绍“javascript异步编程简介”,在日常操作中,相信很多人在Javascript异步编程简介问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Javascri

这篇文章主要介绍“javascript异步编程简介”,在日常操作中,相信很多人在Javascript异步编程简介问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Javascript异步编程简介”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

JavaScript 异步编程简介

回调函数和异步执行

所谓的异步指的是函数的调用并不直接返回执行的结果,而往往是通过回调函数异步的执行。

我们先看看回调函数是什么:

var fn = function(callback) {      // do something here      ...      callback.apply(this, para);  };   var mycallback = function(parameter) {      // do someting in customer callback  };   // call the fn with callback as parameter  fn(mycallback);

回调函数,其实就是调用用户提供的函数,该函数往往是以参数的形式提供的。回调函数并不一定是异步执行的。比如上述的例子中,回调函数是被同步执行的。大部分语言都支持回调,c++可用通过函数指针或者回调对象,Java一般也是使用回调对象。

在Javascript中有很多通过回调函数来执行的异步调用,例如setTimeout()或者setInterval()。

setTimeout(function(){      console.log("this will be exectued after 1 second!");  },1000);

在以上的例子中,setTimeout直接返回,匿名函数会在1000毫秒(不一定能保证是1000毫秒)后异步触发并执行,完成打印控制台的操作。也就是说在异步操作的情境下,函数直接返回,把控制权交给回调函数,回调函数会在以后的某一个时间片被调度执行。那么为什么需要异步呢?为什么不能直接在当前函数中完成操作呢?这就需要了解Javascript的线程模型了。

Javascript线程模型和事件驱动

Javascript最初是被设计成在浏览器中辅助提供html的交互功能。在浏览器中都包含一个Javascript引擎,Javscript程序就运行在这个引擎之中,并且只有一个线程。单线程能都带来很多优点,程序员们可以很开心的不用去考虑诸如资源同步,死多线程阻塞式编程所需要面对的恼人的问题。但是很多人会问,既然Javascript是单线程的,那它又如何能够异步的执行呢?

这就需要了解到Javascript在浏览器中的事件驱动(event driven)机制。事件驱动一般通过事件循环(event loop)和事件队列(event queue)来实现的。假定浏览器中有一个专门用于事件调度的实例(该实例可以是一个线程,我们可以称之为事件分发线程event dispatch thread),该实例的工作就是一个不结束的循环,从事件队列中取出事件,处理所有很事件关联的回调函数(event handler)。注意回调函数是在Javascript的主线程中运行的,而非事件分发线程中,以保证事件处理不会发生阻塞。

Event Loop Code:

while(true) {   var event = eventQueue.pop();   if(event && event.handler) {       event.handler.execute(); // execute the callback in Javascript thread   } else {       sleep(); //sleep some time to release the CPU do other stuff   }  }

通过事件驱动机制,我们可以想象Javascript的编程模型就是响应一系列的事件,执行对应的回调函数。很多UI框架都采用这样的模型(例如Java Swing)。

那为什要异步呢,同步不是很好么?

异步的主要目的是处理非阻塞,在和HTML交互的过程中,会需要一些IO操作(典型的就是ajax请求,脚本文件加载),如果这些操作是同步的,就会阻塞其它操作,用户的体验就是页面失去了响应。

综上所述Javascript通过事件驱动机制,在单线程模型下,以异步回调函数的形式来实现非阻塞的IO操作。

Javascript异步编程带来的挑战

Javascript的单线程模型有很多好处,但同时也带来了很多挑战。

代码可读性

想象一下,如果某个操作需要经过多个非阻塞的IO操作,每一个结果都是通过回调,程序有可能会看上去像这个样子。

operation1(function(err, result) {      operation2(function(err, result) {          operation3(function(err, result) {              operation4(function(err, result) {                  operation5(function(err, result) {                      // do something useful                  })              })          })      })  })

我们称之为意大利面条式(spaghetti)的代码。这样的代码很难维护。这样的情况更多的会发生在server side的情况下。

流程控制

异步带来的另一个问题是流程控制,举个例子,我要访问三个网站的内容,当三个网站的内容都得到后,合并处理,然后发给后台。代码可以这样写:

var urls = ['url1','url2','url3'];  var result = [];   for (var i = 0, len = urls.length(); i < len; i++ ) {      $.ajax({          url: urls[i],          context: document.body,          success: function(){            //do something on success            result.push("one of the request done successfully");            if (result.length === urls.length()) {                //do something when all the request is completed successfully            }          }});  }

上述代码通过检查result的长度的方式来决定是否所有的请求都处理完成,这是一个很丑陋方法,也很不可靠。

异常和错误处理

通过上一个例子,我们还可以看出,为了使程序更健壮,我们还需要加入异常处理。 在异步的方式下,异常处理分布在不同的回调函数中,我们无法在调用的时候通过try...catch的方式来处理异常, 所以很难做到有效,清楚。

更好的Javascript异步编程方式
 

“这是***的时代,也是最糟糕的时代”

为了解决Javascript异步编程带来的问题,很多的开发者做出了不同程度的努力,提供了很多不同的解决方案。然而面对如此众多的方案应该如何选择呢?我们这就来看看都有哪些可供选择的方案吧。

Promise

Promise 对象曾经以多种形式存在于很多语言中。这个词***由C++工程师用在Xanadu 项目中,Xanadu 项目是WEB 应用项目的先驱。随后Promise 被用在E编程语言中,这又激发了python 开发人员的灵感,将它实现成了Twisted 框架的Deferred 对象。

2007 年,Promise 赶上了JavaScript 大潮,那时Dojo 框架刚从Twisted框架汲取灵感,新增了一个叫做dojo.Deferred 的对象。也就在那个时候,相对成熟的Dojo 框架与初出茅庐的Jquery 框架激烈地争夺着人气和名望。2009 年,Kris Zyp 有感于dojo.Deferred 的影响力提出了Commonjs 之Promises/A 规范。同年,node.js ***亮相。

在编程的概念中,future,promise,和delay表示同一个概念。Promise翻译成中文是“承诺”,也就是说给你一个东西,我保证未来能够做到,但现在什么都没有。它用来表示异步操作返回的一个对象,该对象是用来获取未来的执行结果的一个代理,初始值不确定。许多语言都有对Promise的支持。

Promise的核心是它的then方法,我们可以使用这个方法从异步操作中得到返回值,或者是异常。then有两个可选参数(有的实现是三个),分别处理成功和失败的情景。

var promise = doSomethingAync()  promise.then(onFulfilled, onRejected)

异步调用doSomethingAync返回一个Promise对象promise,调用promise的then方法来处理成功和失败。这看上去似乎并没有很大的改进。仍然需要回调。但是和以前的区别在于,首先异步操作有了返回值,虽然该值只是一个对未来的承诺;其次通过使用then,程序员可以有效的控制流程异常处理,决定如何使用这个来自未来的值。

对于嵌套的异步操作,有了Promise的支持,可以写成这样的链式操作:

operation1().then(function (result1) {      return operation2(result1)  }).then(function (result2) {      return operation3(result2);  }).then(function (result3) {      return operation4(result3);  }).then(function (result4) {      return operation5(result4)  }).then(function (result5) {      //And so on  });

Promise提供更便捷的流程控制,例如Promise.all()可以解决需要并发的执行若干个异步操作,等所有操作完成后进行处理。

var p1 = async1();  var p2 = async2();  var p3 = async3();  Promise.all([p1,p2,p3]).then(function(){      // do something when all three asychronized operation finished  });

对于异常处理,

doA()    .then(doB)    .then(null,function(error){        // error handling here    })

如果doA失败,它的Promise会被拒绝,处理链上的下一个onRejected会被调用,在这个例子中就是匿名函数function(error){}。比起原始的回调方式,不需要在每一步都对异常进行处理。这生了不少事。

以上只是对于Promise概念的简单陈述,Promise拥有许多不同规范建议(A,A+,B,KISS,C,D等),名字(Future,Promise,Defer),和开源实现。大家可以参考一下的这些链接。

  • jQuery's Deferred Object

  • YUI Promise Class

  • Dojo Promises

  • Q

  • RSVP.js

  • When.js

  • MochiKit.Async

  • FutureJS

  • node-promise

  • WinJS


如果你有选择困难综合症,面对这么多的开源库不知道如何决断,先不要急,这还只是一部分,还有一些库没有或者不完全采用Promise的概念

Non-Promise

下面列出了其它的一些开源的库,也可以帮助解决Javascript中异步编程所遇到的诸多问题,它们的解决方案各不相同,我这里就不一一介绍了。大家有兴趣可以去看看或者试用一下。

  • Node-fibers

  • Streamlinejs

  • Step

  • Flow-js

  • Async

  • Async.js

  • slide-flow-control

Non-3rd Party

其实,为了解决Javascript异步编程带来的问题,不一定非要使用Promise或者其它的开源库,这些库提供了很好的模式,但是你也可以通过有针对性的设计来解决。

比如,对于层层回调的模式,可以利用消息机制来改写,假定你的系统中已经实现了消息机制,你的code可以写成这样:

eventbus.on("init", function(){      operationA(function(err,result){          eventbus.dispatch("ACompleted");      });  });   eventbus.on("ACompleted", function(){      operationB(function(err,result){          eventbus.dispatch("BCompleted");      });  });   eventbus.on("BCompleted", function(){      operationC(function(err,result){          eventbus.dispatch("CCompleted");      });  });   eventbus.on("CCompleted", function(){      // do something when all operation completed  });

这样我们就把嵌套的异步调用,改写成了顺序执行的事件处理。

更多的方式,请大家参考这篇文章,它提出了解决异步的五种模式:回调、观察者模式(事件)、消息、Promise和有限状态机(FSM)。

下一代Javscript对异步编程的增强

ECMAScript6

下一代的Javascript标准Harmony,也就是ECMAScript6正在酝酿中,它提出了许多新的语言特性,比如箭头函数、类(Class)、生成器(Generator)、Promise等等。其中Generator和Promise都可以被用于对异步调用的增强。

nodejs的开发版V0.11已经可以支持es6的一些新的特性,使用node --harmony命令来运行对ES6的支持。

co、Thunk、Koa

koa是由Express原班人马(主要是TJ)打造,希望提供一个更精简健壮的nodejs框架。koa依赖ES6中的Generator等新特性,所以必须运行在相应的Nodejs版本上。

利用Generator、co、Thunk,可以在Koa中有效的解决Javascript异步调用的各种问题。

co是一个异步流程简化的工具,它利用Generator把一层层嵌套的调用变成同步的写法。

var co = require('co');  var fs = require('fs');   var stat = function(path) {    return function(cb){      fs.stat(path,cb);    }  };   var readFile = function(filename) {    return function(cb){      fs.readFile(filename,cb);    }  };   co(function *() {    var stat = yield stat('./README.md');    var content = yield readFile('./README.md');  })();

通过co可以把异步的fs.readFile当成同步一样调用,只需要把异步函数fs.readFile用闭包的方式封装。

利用Thunk可以进一步简化为如下的code, 这里Thunk的作用就是用闭包封装异步函数,返回一个生成函数的函数,供生成器来调用。

var thunkify = require('thunkify');  var co = require('co');  var fs = require('fs');   var stat = thunkify(fs.stat);  var readFile = thunkify(fs.readFile);   co(function *() {    var stat = yield stat('./README.md');    var content = yield readFile('./README.md');  })();

利用co可以串行或者并行的执行异步调用。

串行

co(function *() {    var a = yield request(a);    var b = yield request(b);  })();

并行

co(function *() {   var res = yield [request(a), request(b)];  })();

到此,关于“Javascript异步编程简介”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Javascript异步编程简介

本文链接: https://www.lsjlt.com/news/79808.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Javascript异步编程简介
    这篇文章主要介绍“Javascript异步编程简介”,在日常操作中,相信很多人在Javascript异步编程简介问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Javascri...
    99+
    2022-10-19
  • 异步编程之asyncio简单介绍
    引言: python由于GIL(全局锁)的存在,不能发挥多核的优势,其性能一直饱受诟病。然而在IO密集型的网络编程里,异步处理比同步处理能提升成百上千倍的效率,弥补了python性能方面的短板. asyncio是做什么的 异步网络操作 ...
    99+
    2023-01-30
    简单 asyncio
  • JavaScript异步编程操作实现介绍
    目录异步编程同步模式与异步模式同步模式(Synchronous)异步模式(Asynchronous)回调函数PromisePromise基本用法Promise使用案例Promise常...
    99+
    2022-11-13
  • Node.js 异步编程之 Callback介绍(一)
    Node.js 基于 JavaScript 引擎 v8,是单线程的。Node.js 采用了与通常 Web 上的 JavaScript 异步编程的方式来处理会造成阻塞的I/O操作。在 Node.js 中读取文...
    99+
    2022-06-04
    Node js Callback
  • JavaScript异步编程的用法
    这篇文章将为大家详细讲解有关JavaScript异步编程的用法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在一年前初学js的时候,看过很多关于异步编程的讲解。但是由于实...
    99+
    2022-10-19
  • JavaScript异步编程的使用
    这篇文章主要介绍“JavaScript异步编程的使用”,在日常操作中,相信很多人在JavaScript异步编程的使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JavaSc...
    99+
    2022-10-19
  • Laravel和JavaScript的异步编程与Python的异步编程有何不同?
    随着计算机技术的不断发展,异步编程已经成为了现代编程中的一个非常重要的概念。许多编程语言都提供了异步编程的支持,如Laravel、JavaScript和Python等。虽然它们都可以实现异步编程,但是它们之间的实现方式有所不同。本文将探讨...
    99+
    2023-09-08
    异步编程 laravel javascript
  • Pythonasyncio异步编程简单实现示例
    目录一、asyncio事件循环简介二、async协程函数简介三、await关键字四、async异步编程简单实现今天继续给大家介绍Python相关知识,本文主要内容是Python as...
    99+
    2023-01-18
    Python asyncio异步 Python asyncio
  • Javascript异步编程是怎样的
    本篇文章给大家分享的是有关Javascript异步编程是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。这可能是个比较深的话题。何谓异步?...
    99+
    2022-10-19
  • 异步的含义以及JavaScript异步编程的方法
    本篇内容主要讲解“异步的含义以及JavaScript异步编程的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“异步的含义以及JavaScript异步编程的方法...
    99+
    2022-10-19
  • 微信小程序如何实现异步API为Promise简化异步编程
    这篇文章主要介绍了微信小程序如何实现异步API为Promise简化异步编程,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。把微信小程序异步AP...
    99+
    2022-10-19
  • javascript异步编程有哪些方式
    这篇文章主要为大家展示了“javascript异步编程有哪些方式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“javascript异步编程有哪些方式”这篇文章吧...
    99+
    2022-10-19
  • Python 异步编程能否响应 javascript?
    随着Web应用程序的普及,JavaScript已经成为了前端开发的标配语言。而Python也因其易学易用而成为了数据科学、Web后端等领域的热门语言。在这两个语言的交汇点上,我们不禁要问一句:Python 异步编程能否响应 JavaScri...
    99+
    2023-07-27
    异步编程 响应 javascript
  • 并发编程 | 从Future到CompletableFuture - 简化 Java 中的异步编程
    引言 在并发编程中,我们经常需要处理多线程的任务,这些任务往往具有依赖性,异步性,且需要在所有任务完成后获取结果。Java 8 引入了 CompletableFuture 类,它带来了一种新的编程模式,让我们能够以函数式编程的方式处理并发任...
    99+
    2023-08-19
    java 后端
  • python第三方异步日志库loguru简介
    目录一、引言二、安装loguru三、特性3.1 开箱即用3.2 无需初始化,导入函数即可使用3.3 更容易的文件日志记录与转存/保留/压缩方式3.4 更优雅的字符串格式化输出3.5 ...
    99+
    2022-12-24
    python异步日志库loguru 第三方异步日志库loguru python日志库loguru python loguru
  • JavaScript异步编程中async函数详解
    目录async函数await 表达式async使用形式async读取文件async发送AJAX请求与生成器(Generator)相比async函数 async函数的返回值为 prom...
    99+
    2022-11-13
    JavaScript async JavaScript异步编程 JS async
  • JavaScript中异步编程的示例分析
    这篇文章给大家分享的是有关JavaScript中异步编程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。目的提升开发效率,编写易维护的代码引子问题请求时候为什么页面卡死??$.ajax({ &n...
    99+
    2023-06-15
  • .NET异步编程模式的三种类型介绍
    一、引言 .NET中很多的类、接口在设计的时候都考虑了多线程问题,简化了多线程程序的开发,不用自己去写WaitHandler等这些底层的代码,由于历史的发展,这些类的接口设计有着三种...
    99+
    2022-11-13
  • JavaScript异步编程之Promise的初步使用详解
    1. 概述 Promise对象是ES6提出的的异步编程的规范。说到异步编程,就不得不说说同步和异步这两个概念。 从字面意思理解同步编程的话,似乎指的是两个任务同步运行,如果这样理解就...
    99+
    2022-11-12
  • path 框架:让 Python 异步编程变得更简单
    Path 框架:让 Python 异步编程变得更简单 Python 是一种非常流行的编程语言,特别是在数据科学和机器学习领域。然而,Python 在处理大量并发请求时可能会遇到性能瓶颈。这时候异步编程就成为了解决问题的一种有效方法。Path...
    99+
    2023-11-10
    异步编程 框架 path
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作