前言:
异步:现在与未来的理解?
假设我们在运行一段for循环,开始到结束的过程,当然这也需要持续一段时间(几微秒或几毫秒)才能完成。它是指程序的一部分现在执行,而另一部分则将来运行。现在与将来之间有段间隙,在这段间隙中,程序没有活跃执行其它程序,而是等待for循环的完成。这将浪费了这段间隙的时间,给了用户很不好的体验。我们需要管理这段时间间隙,这段间隙可能是在等待用户输入、从数据库或文件系统中请求数据、通过网络发送数据并等待响应。或者是在以固定时间间隔执行重复任务等等。这些情况我们都需管理这段时间间隔的状态。在接下来这几篇博客,我们将学习新出现的JS异步编程技术。
这篇博客不会谈到异步编程技术,我们先深入理解异步的概念及在JS中的运作模式。将在接下来的博客深入讲解回调函数和Promise异步编程技术
1.1 分块程序
我们可以把JS的程序写在单个.js文件中,但是这个程序几乎是由多个块构成的。在这些块中只有一个是现在执行的,其余的则会在将来执行。最常见的块单位是函数。
我们通常会遇到这样的问题:我们会认为现在无法完成的任务将会异步完成,因此不会对程序造成阻塞行为。
看下面代码:
//假设ajax()是某个库中提供的某个Ajax函数
var data=ajax("http://url");
console.log(data);//哦豁,data通常不会包含Ajax结果。
在打印data时没有Ajax的结果,这是因为Ajax请求不是同步完成的,这就意味着ajax()函数还没有返回任何值可以赋给变量data。如果ajax()能够阻塞到响应返回,那么data赋值就能正确成功。但是我们不能这么做(阻塞),这也不是Ajax的正确使用方法。
现在我们发出一个异步的Ajax请求,然后在将来才能得到返回的结果。
ajax("http://url",function myCallBack(data){
console.log(data);
})
从现在到将来的“等待”,最简单的方法是使用回调函数,但不是唯一和最好的方法。上面的回调函数就是异步(将来)执行的块。
注意:我们可以发送同步的Ajax请求,但是,在任何情况下都不应该这样做,因为它会锁定浏览器的UI界面,使得按钮、菜单、滚动条等无法使用,阻塞了所有的用户交互。
再次举例说明“将来”函数:
function now(){
return 20;
}
function later(){
answer=answer*2;
console.log(answer);
}
var answer=now();
setTimeout(later,1000);
这段程序有两个块(函数):现在执行的now(),将在执行的later()。对它们进行“现在”与“将来”进行划分。
现在:
function now(){
return 20;
}<