某天忽然写了个方法要从后台调用数据,显示在前台页面,可是输出结果老是空undefined,得不到数据。多方找资料才发现,原来是入了JS异步的“坑”。ajax
咱们经常听到单线程、多线程、同步、异步这些概念,那么这些东西究竟是什么呢?
那么咱们先从上面那几个概念提及 o( ̄▽ ̄)ブ网络
每一个正在运行的程序(即进程)至少有一个线程,被称为主线程。主线程在启动程序时被建立,用于执行main函数。多线程
单线程就是只有一个主线的线程,代码从上往下顺序运行,主线程负责执行程序的全部代码(UI展示以及刷新,网络请求,本地存储等等)【一个线程要作全部的事情,想一想都有点累呢】并发
多线程顾名思义,就是有多个线程的程序,能够由用户自主建立。用户自主建立的若干进程相对于主线程而言就是子线程。子线程和主线程都是独立的运行单元,各自的执行互不影响,所以可以并发执行。异步
光听这些干巴巴的理论是否是以为有点晕? 巧了,我乍一看的时候也晕。
在找资料的过程当中,我发现了别人的这么一个形象的比喻。函数
打个比方,单线程就是你去厨房又烧饭又烧菜,一我的来回跑;多线程就是两我的,一个单作饭,一个单作菜。spa
这么说,应该更好理解了吧?线程
而什么又是同步和异步呢?调试
咱们用一个简单的生活例子来讲明。code
你打电话订酒店,问工做人员有没有房间,这时候,工做人员须要查找有没有房间才能回答你。
同步就是不挂电话一直等,直到工做人员告诉你有没有房间。
异步就是挂断电话,你去作别的事情,好比吃饭喝水,工做人员查到了信息再打电话告诉你。
那么咱们的主题来了
JS的执行环境是单线程的,也就是说,程序顺序执行下来,一次只能执行一个任务,程序想要往下运行,就必须等待当前的任务执行完毕,无论当前的任务要执行多久(要是后面的程序急着跑出来可真的是等的很难受呢)。
为了解决后面程序等的难受的这个阻塞问题。JavaScript有一种异步处理模式,其实就是延时处理。
咱们再来抛出例子来讲明。
var getUserInfo = function () { $.getJSON("http://www.easy-mock.com/mock/5a09868228b23066479b8379/ajaxData/getUserInfo", function () { return data; }); } var data = getUserInfo(); renderUserInfo(data)
getUserInfo这个函数被调用,要取后台取数据,可能要耗费不少时间,这就要让renderUserInfo一直等着,直到取出data才能运行。幸亏JS有异步操做,取数据的时候,不用renderUserInfo一直等着data取出来,而是直接执行。
这么说的话,那么这两个函数究竟是什么顺序执行的呐?不急,咱们来调试一下:
var getUserInfo = function () { console.log('aaa'); $.getJSON("http://www.easy-mock.com/mock/5a09868228b23066479b8379/ajaxData/getUserInfo", function () { console.log('bbb'); return data; }); } var data = getUserInfo(); console.log(data); console.log('ccc'); renderUserInfo(data);
顺序执行下来的输出原觉得是"aaa","bbb","ccc"吧?
然而事情并无这么简单。咱们来看一下控制台的输出:
输出的结果居然不是顺序的。
也就是说函数执行到getJSON取数据的时候,程序并无等它取出数据再执行下一步,而是跳过了取数据这一个阶段,直接执行输出data了,所以,data也为空。
这就是JS的异步机制了。