1、同步与异步

异步: 可以多条任务线去执行程序,一条任务卡顿不影响其他任务。

2、异步数据场景

  1. function getData(){
  2. setTimeout(() => {
  3. let data = "hello world"; //模拟一个异步数据
  4. return data; //return只能返回同步的数据
  5. },500)
  6. }
  7. let data = getData();
  8. console.log(data) //值为undefined,普通函数无法通过返回值返回异步数据。

3、回调函数

回调函数是将函数作为参数传递给另一个函数,通过回调函数可以获取异步数据,实例代码如下所示:

  1. function getData( next ){ //参数为一个函数
  2. setTimeout(() => {
  3. let data = "hello world"; //模拟一个异步数据
  4. next(data); //将数据传递给这个函数
  5. },500)
  6. }
  7. getData((data) => {
  8. console.log(data); //可以获取到异步数据
  9. })

接下来制作一个案例巩固这个例子:定义两个异步获取数据的函数,一个是getFirstName,另一个是getLastName,将两个函数获取到的数据连接成为一个名字,实例代码如下所示:

  1. function getFirstName( next ){
  2. setTimeout(() => {
  3. let data = "李";
  4. next(data);
  5. },500)
  6. }
  7. function getLastName( next ){
  8. setTimeout(() => {
  9. let data = "小明";
  10. next(data);
  11. },500)
  12. }
  13. getFirstName(first => {
  14. getLastName( last => {
  15. let name = first + last;
  16. console.log(name);
  17. })
  18. })

虽然成功获取到了数据,但是通过上面的例子,我们发现,多个异步数据使用回调函数来嵌套,代码的维护成本会越来越高,接下来,我们使用es2015的语法来逐步优化这个案例。

4、promise对象

在ES2015中新加入了Promise对象,Promise对象用来解决异步问题,关于异步问题,我们会在第8章详细讲解,本章只要概括性地了解Promise对象的语法即可,创建一个Promise对象的语法如下所示:

  1. // resolve的作用是把异步获取的数据结果传递出来。
  2. let getData = new Promise((resolve) => {
  3. let data = "string data";
  4. resolve(data);
  5. })

Promise构造函数的参数是一个函数,而函数的形参resolve同样也是一个函数,调用resolve可以将数据从promise对象中传递出来。

使用Promise对象,模拟刚才的异步获取数据,实例代码如下所示:

  1. // promise的构造函数,需要传递一个参数
  2. function getLastName(){
  3. return new Promise(function(resolve){
  4. // resolve也是一个函数
  5. setTimeout(() => {
  6. let data = "小明"
  7. resolve(data);
  8. },500)
  9. });
  10. }
  11. // 客户端代码
  12. let promise = getLastName();
  13. promise.then(function(d){
  14. console.log(d);
  15. })

使用Promise对象,定义刚才案例中的两个函数,一个是getFirstName,另一个是getLastName,将两个函数获取到的值链接到一起。

5、async函数

async函数

async函数与Promise对象结合使用,可以优雅地处理异步问题,声明async函数的语法如下所示:

  1. async function fun(){
  2. //async函数内部可以使用await关键字
  3. }

我们用一个实际的案例来讲解async函数与Promise对象的用法。

在Promise对象的示例中,我们用resolve函数将数据传递出来之后,然后可以用async函数中的await关键字接收数据,完整的实例代码如下所示。

  1. // resolve的作用是把异步获取的数据结果传递出来。
  2. let getData = new Promise((resolve) => {
  3. let data = "string data";
  4. resolve(data);
  5. })
  6. async function showData(){
  7. let data = await getData;
  8. console.log(data)
  9. }
  10. showData();

await后面跟着一个Promise对象,可以获取到Promise对象内部resolve传递出来的数据,这这里需要注意的是:

await关键字必须写在async函数内部。