[聚合文章] 由一道JS异步面试题,思考对异步问题的处理(1)

Ajax 2017-12-11 14 阅读

问题图示如下

再进一步说明问题

  • 按钮A按了之后,ajax请求的数据显示在input type=text框里,B按钮也是。

  • 问题就是如果先按A,此时ajax发出去了,但是数据还没返回来, 我们等不及了,马上按B按钮,结果此时A按钮请求的数据先回来,这就尴尬了,按的b按钮,结果先显示A按钮返回的数据,怎么解决?

这个问题的解释在我之前写的一篇文章,其中的第二题就是解决方案 juejin.im/post/5a1810… ,我们今天把这个问题展开

一、js的异步的运行机制是什么

以下是一张解释异步队列的图,以及文字说明(摘自阮一峰老师的博客)

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

之后,我们来看一个异步引发的问题代码

var res = [];  
  
function response(data) {  
    res.push( data );  
}  
  
// ajax(..)是某个库中提供的某个Ajax函数  
ajax( "http://some.url.1", response );  
ajax( "http://some.url.2", response );

问题来了,我们假定期望的行为是res[0] 中放调用"http://some.url.1" 的结果,res[1] 中放调用"http://some.url.2" 的结果,改怎么办呢? 解决办法如下

var res = [];  
function response(data) {  
    if (data.url == "http://some.url.1") {  
        res[0] = data;  
    }  
  
    else if (data.url == "http://some.url.2") {  
        res[1] = data;  
    }  
}  
  
// ajax(..)是某个库中提供的某个Ajax函数  
ajax( "http://some.url.1", response );  
ajax( "http://some.url.2", response );

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。