读《javascript异步编程》

原创
2014/07/08 23:40
阅读数 349

1、避免异步回调函数的递归,大量延时的话,会造成巨大的计算荷载。

var count = 100;

function test(){
    setTimeout(function(){
        console.log('count--');
        count-- && test();
    }, 100);
}

test();

2、如果有函数既要返回值,又要使用回调函数,务必使回调异步执行,以确保返值已经获取并可以使用。

var webSocketCache = {};
 
function openWebSocket(serverAddress, callback) { 
  var socket; 
  if (serverAddress in webSocketCache) { 
    socket = webSocketCache[serverAddress];
 
    if(socket.readyState === WebSocket.OPEN) { 
      callback(); 
    } else { 
      socket.onopen = _.compose(callback, socket.onopen); 
    }; 

  } else { 

    socket = new WebSocket(serverAddress); 
    webSocketCache[serverAddress] = socket; 
    socket.onopen = callback; 
  }; 

  return socket; 
};

var socket = openWebSocket(url, function(){ 
  socket.send('Hello, server!'); 
});

/*
(这段代码依赖于Underscore.js库。_.compose定义的这个新函数既
运行了callback,又运行了初始的socket.onopen回调。)

这段代码的问题在于,如果套接字已经缓存且打开,则会在函数返值
之前就运行回调,这会使以下代码崩溃。
*/

//怎么解决呢?将回调封装在setTimeout中即可。
if (socket.readyState === WebSocket.OPEN) { 
  setTimeout(callback, 0); 
} else{
  // ... 
}



3、缓存型异步函数调用时,出现未载入的错误。

比如常用的jquery内容加载完成后的运行js的方法:

// application.js 
$(function() { 
  utils.log('Ready'); 
}); 

// utils.js 
window.utils = { 
  log: function() { 
    if(window.console) console.log.apply(console, arguments); 
  } 
}; 

<scriptsrc ="application.js"></script>
<script src ="util.js"></script>

第一次运行没有问题,因为没有缓存,能找到utils。

但有缓存后,再运行application.js时,就会报utils未定义的错误,因为这时候jquery会判断已加载所有文档。

也算是jquery的一个bug吧,不过在新版里已经修复了。

4、请避免两层以上的函数嵌套

5、try/catch无法捕获异步函数里的异常,不要在异步函数内抛出异常,除非是致命的安全错误

6、一次性事件对象应使用Promise对象处理异步函数,如ajax的请求。

7、为了更好地解耦与开发,使用Pub/sub模式更好,优于事件模式。

8、异步并行时,可以多使用async、step等第三方工作流控制模块。

9、异步脚本加载技术可以使用yepnope和requirejs

10、检测客户端是否支持html5特性可以使用Modernizr库

11、加载css字体的文件、控制UI的js文件等务必放在head中加载

12、无关紧要的js可以用async加载,可以并行加载,加快加载速度,例如分享插件

13、多数浏览器不支持async,但支持defer,async会覆盖defer

<html> 
<head> 

<!-- meta data and stylesheets go here --> 
<script src="headScripts.js"></scripts> 
<script src="deferredScripts.js" defer></script> 
</head> 

<body> 
<!-- content goes here --> 
<script async defer src="feedbackWidget.js"></script> 
<script async defer src="chatWidget.js"></script> 
</body> 

</html>












展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
18 收藏
0
分享
返回顶部
顶部