javascript异步

单线程和异步

JS单线程

JS是单线程语言,只能同时做一件事。

浏览器和node.js已支持JS启动进程,如Web Worker

JS和DOM渲染共用同一个线程,因为JS可修改DOM结构

异步原因

遇到等待(网络请求,定时任务)不能卡住

需要异步

回调callback函数形式

异步和同步

基于JS是单线程语言
异步不会阻塞代码执行
同步会阻塞代码执行

异步 (callback 回调函数)

console.log(100)
setTimeout(() => {
    console.log(200)
}, 1000) // 最后打印
console.log(300)
console.log(400)

同步

console.log(100)
alert(200) // 点击ok才能打印300
console.log(300)

应用场景

网络请求,如ajax图片加载

console.log('start')
$.get('./data.json',function(data){
  console.log(data)
})
console.log('end')

定时任务,如setTimeout

Promise

callback hell回调地狱

//获取第一份数据
$.get(url1, (data1) => {
  console.log(data1);
  //获取第二份数据
  $.get(url2, (data2) => {
    console.log(data2);
    //获取第三份数据
    $get(url3, (data3) => {
      console.log(data3);
      //还可能获取更多的数据})
    });
  });
});

Promise封装ajax

封装

getData = (url) => {
  return new Promise((resolve, reject) => {
    $.ajax({
      url,
      success(data) {
        resolve(data);
      },
      error(err) {
        reject(err);
      },
    });
  });
};

使用

const url1 = "/data1.json";
const url2 = "/data2.json";
const url3 = "/data3.json";

getData(url1)
  .then((data1) => {
    console.log(data1);
    return getData(url2);
  })
  .then((data2) => {
    console.log(data2);
    return getData(url3);
  })
  .then((data3) => {
    console.log(data3);
  })
  .catch((err) => console.error(err));