本文是一个针对js新手,写一个超级浅薄的入门,解释一下js的异步编程概念以及使用。主要目的是让新手可以超级快速上手简单的异步编程代码。如果想了解异步编程的底层实现,请跳过本文。
1 为什么有异步编程?
js是一门单线程的语言。说人话就是js同一时间只干一件事。
接下来请先记住:
先执行同步函数,再执行异步函数。
我们举个具体场景:
js是主要执行在浏览器中的语言,需要考虑到用户体验。有些方法执行时间很长(比如从后端中获取一张图片加载在前端),如果按顺序做这个任务,用户只能干等。因此,解决方案就是先做一些执行速度快的事情让用户感觉这个网页正在加载。
在这个场景中,我们的异步编程就是把这个执行时间长的方法放到后面做,而快捷的事情优先做。这些放到后面的方法,我们称为异步函数。
整个js的工作流程就是:先执行同步函数(快的任务),再执行异步函数(慢的任务)。
2 异步函数的跟屁虫
一般来说,异步函数会有个跟屁虫,就是回调函数。回调函数在异步函数执行完成后执行。可以简单理解为,回调函数是异步函数的组成部分。
接下来请先记住:
先执行同步函数,再执行异步函数,紧跟异步函数执行回调函数
在js中,函数是可以作为另一个函数的参数的,举个例子:
function print(x){ //print有一个的参数x。print的作用是打印x的值
console.log(x);
}
function fun(y, print){ //fun有两个参数,一个是某个值y,一个是函数print。作用是用print函数打印y
print(y);
}
fun(“异步是个什么鬼”,print); //控制台输出:’异步是个什么鬼‘
所谓回调函数,就是一个函数作为参数传入一个异步函数中,异步函数再完成本来的工作后,立马调用这个回调函数。也就是异步函数先干活,干完活后跟屁虫立马干活。例如:
function print(){ //print的作用是打印"我是一个回调函数"
console.log("我是一个回调函数");
}
d3.csv(filename, print()); //d3.csv是一个d3库中的异步函数,用来读取filename代表的这个csv文件中的内容。print是回调函数。
这个代码会先读取csv文件,然后立刻打印“我是一个回调函数”。
3 异步函数和跟屁虫有什么效果
先执行同步函数,再执行异步函数,紧跟异步函数执行回调函数
我们结合代码来看一下异步函数如何执行。
function print(){ //print的作用是打印"我是一个回调函数"
console.log("我是一个回调函数");
}
d3.csv(filename,print()); //异步函数,功能是d3库中读取csv文件,然后立刻打印“我是一个回调函数”
console.log("同步函数"); //console.log是一个同步函数。
以上代码有什么效果:
首先打印“同步函数”(同步函数)
第二读取csv文件(异步函数)
最后打印“我是一个回调函数”(回调函数)
4 如何简单地让异步函数按我的代码顺序执行?
法一:同步函数当作跟屁虫来执行
function print(){ //print的作用是打印"我是一个回调函数"
console.log("同步函数"); //console.log是一个同步函数。
console.log("我是一个回调函数");
}
d3.csv(filename,print()); //异步函数,功能是d3库中读取csv文件,然后立刻打印“我是一个回调函数”
以上代码效果:
首先读取csv文件(异步函数)
第二打印“同步函数”(在回调函数中执行同步函数)
最后打印“我是一个回调函数”(回调函数)
法二:async await语法糖。
async一定要配合await使用。async没啥用,但是有async,我们才能使用await。
await的作用是停下来等异步函数先执行,不把异步函数扔到最后去。
function print(){ //print的作用是打印"我是一个回调函数"
console.log("我是一个回调函数");
}
async function func(){ //声明一个异步函数
await d3.csv(filename,print()); //等待异步函数执行完
console.log("同步函数"); //执行完异步函数后再执行同步函数
}
//真正开始工作
func(); //调用func函数
以上代码效果:
首先读取csv文件(异步函数)
第二打印“我是一个回调函数”(回调函数)
最后打印“同步函数“(同步函数)
先执行同步函数,再执行异步函数,紧跟异步函数执行回调函数
5 题目
chenhui.li中
ecnu数据可视化week5第2题的执行逻辑应该是:
先读取csv,再画图。
读取csv的d3.csv()是异步函数,画图是同步函数,怎么做呢?套用上文的两个方法:
法一:画图作为d3.csv()的回调函数。那么执行逻辑就是:d3.csv(异步函数)=>画图(在回调函数中执行同步函数)
法二:
async function func(){ //声明一个异步函数
await d3.csv(filename,()); //等待异步函数执行完
画图();
}
func();
执行逻辑就是:d3.csv(异步函数)=>画图(等待异步函数完成后执行同步函数)。