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>