JavaScript异步编程教程(1)深入理解JavaScript事件
沉沙 2018-10-25 来源 : 阅读 1277 评论 0

摘要:本篇教程介绍了JavaScript异步编程教程(1)深入理解JavaScript事件,希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入。

本篇教程介绍了JavaScript异步编程教程(1)深入理解JavaScript事件,希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入。

<

事件的调度
 JavaScript事件处理器在线程空闲之前不会运行
 
 线程的阻塞

var start = new Date();

 
// setTimeout和setInterval的计时精度比期望值差

setTimeout(function(){

         var end = new Date();

         console.log(‘Time elapsed‘, end - start, ‘ms‘);

}, 500);

 
while(new Date - start < 1000) {};


  结果上看出setTimeout没有使用另一线程
 
  队列
  调用setTimeout时,会有一个延时事件排入队列;
  输入事件的工作方式完全一样,如单机事件发生时,会有一个单击事件排入队列。但是,单击事件处理器要等到当前所有正在运行的代码均结束后才会执行。
 
?异步函数类型
  两大类:I/O函数和计时函数
 
  异步的I/O函数
  Node.js的出现是为了建立一个在某高级语言之上的事件驱动型服务器框架。
  JavaScript语言可以完美地实现非阻塞式I/O。
  如:
  var ajaxRequest = new XMLRequest();
  ajaxRequest.open(‘GET’, url);
  ajaxRequest.send(null);
  // 只需要附加一个事件处理器,随即返回事件队列
  ajaxRequest.onreadystatechange = function() {
   // …
  }
  因此,开发者需要做的只是定义一个回调就可以了。
 
  WebKit的console.log是异步的吗?
 

  var a = {name: ‘1‘};

  console.log(a);

  a.name = ‘2‘;

  console.log(a);

  执行后打开控制台结果:

  先打开控制台,然后再执行的结果:
  
  原因:
  Console是浏览器的控制台所提供的对象,只有在控制台打开时才起作用;
  console.log并没有立即拍摄对象快照,只是存储了一个对象的引用;
 
  异步的计时函数
  可能为了作动画或模拟;
 
  setTimeout与setInterval(不精确的计时工具)
  以上两个函数的缺陷:即使时延设置为0,在浏览器中的执行频率也大约为200次/秒;
  原因:HTML规范推行的延时/时隔最小值为4毫秒;
  需要更细粒度计时的方案:requestAnimationFrame函数
 
?异步函数的编写
  任何函数只要使用了异步的函数,从上到下都是异步的。
 
  异步函数的特性:非阻塞
  非阻塞强调了异步函数的高速度
 
  间或异步的函数
  有些函数某些时候是异步的,但其他时候却不然;
  例:jQuery的同名函数可用于延迟函数直到DOM已经结束加载;
      但DOM如果早已结束了加载,则不存在任何延迟,$的回调将会立即触发;
 
  // application.js
  $(function() {
       utils.log(‘Ready‘);
  });
 
  // utils.js
  window.utils = {
          log: function() {
                  if(window.console)
                        console.log.apply(console, arguments);
          }
  };
  <script src="application.js" type="text/javascript"> </script>
  <script src="utils.js" type="text/javascript"> </script>
 
  这段代码运行得很好,但前提是浏览器并未从缓存中加载页面(这会导致DOM 早在脚本运行之前就已加载就绪)。如果出现这种情况,传递给$的回调就会在设置utils.log 之前运行,从而导致一个错误。
 
  缓存型异步函数
  function runCalculation(formula, callback) {
    if (formula in calculationCache) {
        return callback(calculationCache[formula]);
    };
    if (formula in calculationCallbacks) {
        return setTimeout(function() {
            runCalculation(formula, callback);
        }, 0);
    };
    mathWorker.postMessage(formula);
    calculationCallbacks[formula] = callback;
 }
  公式已经计算完成,于是结果位于calculationCache 中。这种情况下,runCalculation 是同步的。
  公式已经发送给Worker 对象,但尚未收到结果。这种情况下,runCalculation 设定了一个延时以便再次调用自身;重复这一过程直到结果位于calculationCache 中为止。
 
  异步递归与回调存储
  避免异步递归,尽量采用回调存储。
 
  返值与回调
  永远不要定义一个潜在同步而返值却有可能用于回调的函数。
  避免使用计时器方法来等待某个会变化的东西。如果同一个函数既返值又运行回调,则请确保回调在返值之后才运行。
 
?异步错误的处理
  大多数JavaScript环境会提供一个有用的堆栈轨迹。
 
  回调内抛出的错误

setTimeout(function A() {
    setTimeout(function B() {
        setTimeout(function C() {
            throw new Error(‘Something terrible has happened!‘);
        }, 0);
      }, 0);
}, 0);


 A和B并未出现在堆栈轨迹中,因为这三个函数都是从事件队列直接运行的;
  同理,try/catch语句块不能捕获从异步回调中抛出的错误;
  要记住的是,只能在回调内部处理源于回调的异步错误。
  windows.onerror 处理器返回true,能阻止浏览器的默认错误处理行为。
  避免两层以上的函数嵌套。关键是找到一种在激活异步调用之函数的外部存储异步结果的方式,这样回调本身就没有必要再嵌套了。    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端JavaScript频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程