JavaScript中的异步
你好,我是麦小子。
正如标题所讲,今天咱们要讨论的点是异步。
如果你对"异步"这个概念没有概念的话——正好,咱们从头开始。
生活中的异步
有个很有意思的问题,来自童年一部不错的动画片。
洗衣服(洗衣机)需要50min
烧水需要10min
吃饭需要20min
请问,做完这三件事一共需要几分钟?
如果你不加思考,张口就来。会不会回答80min呢?我想这是有可能的。因为当年我也是这么回答的,这个回答有错吗?显然是正确的,却不合逻辑。事实上,要做完以上三件事在最理想的状态下仅需50min.
80min和50min
两个答案都是正确的,不同的是思考方式或者生活方式。
前者需等某一件事做完才会去做第二件,后者在洗衣机工作时就已经开始烧水和吃饭了,做完这两件事甚至衣服还没洗完呢。
我们给这两种不同的方式以不同的名字
前者被称为同步
后者被称为异步
看起来,异步让小伙子显得更机灵。
JS中的异步
一颗栗子
吃完上面的栗子~下面来打另外一颗。这次咱们引入一段JS代码。
console.log('hello');
setTimeout(() => {
console.log('setTimeout') }, 2000);
console.log('JavaScript');
它的打印结果可能会出乎意料
hello
JavaScript
setTimeout
原因很简单,setTimeout()函数是一个异步函数。
我们知道,作为一个定时器设置函数。setTimeout()可以让程序在一段时间后调用某个函数(或执行某段代码)。正如前文所表,我们设置了2000毫秒之后打印 setTimeout 。
接下来,我们把浏览器想象成一个小伙子。
首先,他看到第一行代码,指令是打印一个 hello ,于是他往控制台打印一个 hello
然后,他看到第二行代码,创建了一个定时器,于是他就在那等着,等时间到了就去执行代码。可是转念一想,老这么等着也不是个事,干脆,我先看看后面还有指令不。
接着,他暂时离开了定时器,发现了第三行代码,指令是打印一个 JavaScript ,于是他往控制台打印一个 JavaScript
接下来,他发现在此之后已经没有可执行的代码,猛然想起,还有一个定时器呢~得回去看看。当他再一次遇到那个定时器,发现时间还没到。
于是,他就又等了一段时间。
后来,时间总算到了。他终于可以执行定时器里的代码了,指令是打印一个 setTimeout 于是它打印了一个 setTimeout
吃完上面的栗子,相信你对JS异步已经有了轮廓。
回调函数
很久以前,JavaScript 仅支持回调函数来实现异步操作。那么,什么是回调函数?
回调函数是一个被传递到另一个函数中的会在适当的时候被调用的函数,如
const callback = function(){
console.log('this is a callback function');
}
const test = function(callback){
callback();
}
test(callback);
异步返回值
某些情况下,setTimeout 会返回一个值,我们应该如何使用这个返回值?return 吗?
咱们打颗栗子
const countNum = function (value) {
setTimeout(() => {
value *= 2;
}, 2000);
return value;
};
console.log(countNum(2));
- 查看一下打印结果
好想获取异步返回值呀==>2
这样呢?
const countNum = function (value) {
setTimeout(() => {
return value *= 2;
}, 2000);
};
console.log(`好想获取异步返回值呀==>${
countNum(2)}`);
抑或是这样?
const countNum = function (value) {
return setTimeout(() => {
value *= 2;
}, 2000);
};
console.