码迷,mamicode.com
首页 > 其他好文 > 详细

同步调用和异步调用同时存在导致的混乱

时间:2015-06-03 00:44:32      阅读:341      评论:0      收藏:0      [点我收藏+]

标签:

其实在Promise之外也存在这个问题,这里我们以一般的使用情况来考虑此问题。
这个问题的本质是接收回调函数的函数,会根据具体的执行情况,可以选择是以同步还是异步的方式对回调函数进行调用。
下面我们以 onReady(fn) 为例进行说明,这个函数会接收一个回调函数进行处理。


mixed-onready.js

function onReady(fn) {
  var readyState = document.readyState;
  if (readyState == ‘interactive‘ || readyState === ‘complete‘) {
    fn();
  } else {
    window.addEventListener(‘DOMContentLoaded‘, fn);
  }
}
onReady(function () {
  console.log(‘DOM fully loaded and parsed‘);
});
console.log(‘==Starting==‘);

mixed-onready.js会根据执行时的DOM是否装载完毕来决定是对回调函数进行同步或者是异步的调用。


如果在调用onReady之前DOM已经载入的话
  对回调函数进行同步调用
如果在调用onReady之前DOM还没有载入的话
  通过注册 DOMContentLoaded 事件监听器来对回调函数进行异步调用
因此,如果这段代码在源文件中出现的位置不同,在控制台上打印的log消息顺序也会不同。
为了解决这个问题,我们可以选择统一使用异步调用方法。


async-onready.js

function onReady(fn) {
    var readyState = document.readyState;
    if (readyState == ‘interactive‘ || readyState === ‘complete‘) {
        setTimeout(fn, 0);
    } else {
        window.addEventListener(‘DOMContentLoaded‘, fn);
    }
}
onReady(function () {
    console.log(‘DOM fully loaded and parsed‘);
});
console.log(‘==Starting==‘);

关于这个问题,在 Effective JavaScript 23 的 第67项 不要对异步回调函数进行同步调用中也有详细介绍。
  • 绝对不能对异步回调函数(即使在数据已经就绪)进行同步调用。
  • 如果对异步回调函数进行同步调用的话,处理顺序可能会与预期不符,可能带来意料之外的后果。
  • 对异步回调函数进行同步调用,还可能导致栈溢出或异常处理错乱等问题。
  • 如果想在将来某时刻调用异步回调函数的话,可以使用 setTimeout等异步API。
                          — David Herman Effective JavaScript




同步调用和异步调用同时存在导致的混乱

标签:

原文地址:http://www.cnblogs.com/lixiaoyaoslove/p/4548051.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!