同步与异步

异步:

  • AJAX是异步的,request.sent() 后不能直接得到 response,必须等到 readyState 变为4后, 浏览器回头调用request.onreadystatechange 函数才能得到 request.response
  • 轮询
  • 回调 callback: 写了却不调用,给别人调用的函数,就是回调(让别人回头调用一下)
  1. function f1(){}
  2. function f2(fn){
  3. fn()
  4. }
  5. f2(f1) // f1 就是回调

异步与回调的关系:

  • 异步任务需要用回调函数来通知结果,步骤为:
    • JS留一个函数地址给浏览器
    • 异步任务完成时浏览器调用该函数地址
    • 同时把结果作为参数传给该函数
  • 回调函数不一定只在异步任务里,也可以用到同步任务里
  • array.forEach(n => console.log(n)) 就是同步回调

判断异步同步

  • 异步:一个函数的返回值处于setTimeOutAJAXAddEventListener 内部,就是异步函数

总结:

  • 异步任务不能直接拿到结果
  • 于是我们传一个回调给异步任务
  • 异步任务完成时调用回调
  • 调用时把结果作为参数

promise

阮一峰教程
中文文档

  • 异步任务有两个结果:成功或失败
  • 回调三个问题:
    • 命名不规范
    • 回调地狱
    • 不方便捕获错误
  • 为了解决以上三个问题,使用 promiss(1976年提出的思想)

使用 promise 封装 ajax

  1. ajax = (method, url) => {
  2. return new Promise((resolve, reject) => {
  3. const request = new XMLHttpRequest();
  4. request.open(method, url);
  5. request.onreadystatechange = () => {
  6. if (request.readyState === 4) {
  7. // 成功调用 resolve, 失败调用 reject
  8. if (request.status < 400) {
  9. resolve.call(null, request.response);
  10. }else if(request.status >= 400) {
  11. reject.call(null, request);
  12. }
  13. }
  14. }
  15. request.send();
  16. })
  17. }
  18. ajax('GET', './xxx').then(success, fail);
  • 创建 promiss : return new Promise ((resolve, reject) => {})
  • Promise.prototype.then:返回一个 Promise,接收两个参数,Promise 的成功和失败情况的回调函数

    1. Promise.prototype.then(value => {
    2. // fulfillment
    3. }, reason => {
    4. // rejection
    5. });
  • Promise.all:提供了并行执行异步操作的能力,在所有异步操作执行完后才执行回调, 会把所有异步操作的结果放进一个数组中传给 then

    1. Promise.all(iterable);
  • Promise.race:用法与 all 一样,只不过 all 是等所有异步操作都执行完毕后才执行 then 回调。而 race 的话只要有一个异步操作执行完毕,就立刻执行 then 回调

    1. Promise.race(iterable);

    promise 库:axios, jQuery.ajax