Promise

  • js 是单线程语言,也就是同一个时间点,只能处理一个任务

  • 如果存在多个任务,就会进行排队,依次执行


JS 里的任务分为同步任务和异步任务

同步任务:等前一个任务执行完,下一个任务才会开始

异步任务:任务执行,就晾在一边,继续执行下面的任务

// 同步代码
console.log(1)
console.log(2)
// 先输出1,再输出2

// 异步代码
setTimeout(() => {
  console.log(1)
}, 1000)
console.log(2)
先输出21秒后再输出1
  1. 回调函数是什么
function fn() {}

ajax(url, fn); // ajax请求结束后,想要执行一个函数fn,这个函数通常被叫做回调函数
  1. 回调地狱
function fn(url, callback) {
  ajax(url, callback);
}
fn(url, function () {
  fn(url, function () {
    fn(url, function () {
      fn(url, function () {});
    });
  });
});
  1. Promise

    解决了 ES6 以前的异步编程问题,提供一个全新的异步思想,让异步代码更易懂,更美观

    提供强大的函数,如 Promise.all,Promise.race 等…

    Promise 特性:

    1. 对象状态不受外界影响
    2. 状态只会改变一次(一旦改变了,就不会再发生变化)

    Promise 状态:

    1. pending(进行中)
    2. fulfilled(已完成)
    3. rejected(已失败)
  2. Promise 写法

function fn(url) {
  return new Promise((resolve, reject) => {
    ajax(
      url,
      function success() {
        resolve("成功");
      },
      function fail() {
        reject("失败");
      }
    );
  });
}
fn(url)
  .then((res) => {
    return fn(url);
  })
  .then((res) => {
    return fn(url);
  })
  .then((res) => {
    return fn(url);
  })
  .then((res) => {
    return fn(url);
  })
  .then((res) => {
    return fn(url);
  });
  1. then,catch
   promise.then(success, fail);
   // success,成功执行函数
   // fail,失败执行函数 如果没有写,默认抛出 err => { return throw err}
   promise.then(
     (res) => {},
     (err) => {
       return throw err;
     }
   );
`   ````

   ```javascript
   function fn() {
     return new Promise((resolve, reject) => {
       setTimeout(() => {
         resolve(1);
       }, 1000);
     });
   }
   let p = fn(); // promise
   p.then(
     (res) => {
       throw res; // 1
     },
     (err) => {
       console.log(err);
       throw err;
     }
   )
     .catch((err) => {
       // 捕获错误
       console.log("catch", err); // cache, 1
     })
     .then((res) => {
       console.log(res); // undefined
     });
   /*
   1、then/catch结果都是会返回一个Promise对象(显示返回一个promise/被包装成一个promise),所以可以链式调用

   resolve -> then第一个成功回调 -> then抛出一个错误 -> catch捕获
   then第一个回调then1抛出错误不会被第二个回调then2所获取,因为同一个then里面,属于一个promise
   在进到then1这个promise就是不可变的了(pending -> fulfilled),而之后的catch归属于下一个promise(不可变性)
   */
  1. Promise.all
// 多个promise并发执行,等待最后一个完成
// 如果第三个请求接口依赖前两个请求回调
function send(url) {
  return new Promise();
}
Promise.all([send(url), send(url)]).then((res) => {
  let [arr1, arr2] = res;
  send(url).then();
});
  1. Promise.race
// 多个promise并发执行,等待第一个完成
// 如果第三个请求接口依赖前两个请求回调
function send(url) {
  return new Promise();
}
Promise.race([send(url), send(url)]).then((res) => {
  send(url).then();
});