分类 js用法 下的文章


/**
 * 定义类的思路
 *   分析功能
 */
class MyPromise {
  // 创建一个变量存储Promise结果
  _result;
  //   创建一个变量记录promise状态
  _state = 0; //pending0 fufilled1 rejected2
  // 创建一个变量存储回调函数
  _callbacks = [];

  constructor(executor) {
    // 接受一个执行器作为参数
    executor(this._resolve.bind(this), this._reject.bind(this));
  }

  //   私有的resolve() es6中使用#    不使用箭头函数 在类中因严格模式 this=undefined 所以可以使用.bind()重新指定this 且这种情况下函
  //   数在实例对象的原型下更省内存
  _resolve(value) {
    this._result = value;
    // 禁止值被重复修改
    if (this._state !== 0) return;
    this._state = 1;
    // 当resolve执行时说明数据进来了 调用 then的回调函数
    queueMicrotask(() => {
      // 调用callbacks中所有函数
      this._callbacks.forEach((cb) => {
        cb();
      });
    });
  }
  // 箭头函数形式
  //   _resolve=(value)=>{
  //     console.log(this);
  //   }

  //   私有reject()
  _reject(reason) {}

  then(onFufilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      if (this._state == 0) {
        // 说明数据还没进入promise
        // 将回调函数设置为callback
        this._callbacks.push(() => {
          resolve(onFufilled(this._result));
        });
      } else if (this._state == 1) {
        // then的回调函数应放到微任务队列而不是直接调用
        queueMicrotask(() => {
          resolve(onFufilled(this._result));
        });
      }
    });
  }
}

const mp = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("11");
  }, 1000);
});

mp.then((result) => {
  console.log(23, result);
  return 11;
})
  .then((result) => {
    console.log(result);
    return 33;
  })
  .then((result) => {
    console.log(result);
  });

js是单线程的 它的运行基于eventloop事件循环机制。

  1. 调用栈

  栈是一种数据结构 后进先出 
  栈中放的是要执行的代码
 

  1. 任务队列

  队列是一种数据结构,先进先出
  任务队列中是将要执行的代码
  当调用栈的代码执行完毕后 队列中的代码才会按照顺序进入栈中依次执行
  在js中任务队列有两种

  -宏任务队列 (大部分代码)
  -微任务队列 (Promise的回调函数:then,catch,finally.....)
  1. 整个流程

    1.调用栈
    2.微任务队列
    3.宏任务队列
    js中 queueMicrotask()用来向微任务添加任务


 //练习
 console.log(1);

setTimeout(() => console.log(2));

Promise.resolve().then(() => console.log(3));

Promise.resolve().then(() => setTimeout(() => console.log(4)));

Promise.resolve().then(() => console.log(5));

setTimeout(() => console.log(6));

console.log(7);

function sum(a, b, cb) {
  cb(a + b);
}
// sum(111, 222, (result) => {
//   console.log(result);
//   console.log(111);
// });
// 异步调用必须要通过回调函数来返回数据 进行复杂调用会出现回调地狱
/**
 * 问题 异步必须通过回调函数返回结果 回调函数一多出现问题
 * promise解决问题
 * promise:用来存储数据的一个容器 拥有一套特殊的存取数据的方式
 *          使得它可以存储异步调用结果
 */

// 创建promise
// 创建promiSee需要一个函数作为参数
// promise构造函数的回调函数会在创建promise时调用
// 调用时会有两个参数
// const promise = new Promise((resolve, reject) => {
//     // resolve reject 是两个函数 可以向promise中存数据
//     // resolve 在执行正常是存储数据 reject在执行错误是存储数据
//     // 通过函数向promise添加数据好处就是可以用来添加异步调用的数据
//     // resolve('resolve')
//     // throw new Error(111);
//     reject('reject')

// })

// 从promise中读取数据
// 可以通过promise实例方法then来读取promise中存储的数据
// then需要两个回调函数作为参数 用来获取promise中的数据
// 通过resolve存的数据会掉用地一个函数 可以在第一个函数中写处理数据的代码
// 通过reject存储的数据或者出现异常时会调用第二个函数 可以在这写处理又一场的代码

// promise.then((result)=>{
//     console.log(result);
// },(reason)=>{
//     console.log(reason);
// })

// promise中有两个隐藏的属性
// PromiseResult:存的数据
// PromiseState:记录promise状态 只会改变一次
/**
 * fulfilled
 * rejected
 * pending
 *
 *
 * 流程 当promise创建时PromiseState初始值为pending
 * 当通过resolve变为fulfilled调用then的第一个回调函数
 * 当通过reject或出错时 变为rejected PromiseResult变为异常对象调用then的第二个回调函数
 *
 * 当我们通过then读取数据时相当于为promise设置两个回调函数
 */

const promise2 = new Promise((resolve, reject) => {
  resolve("haha");
});

// console.log(promise2);
// promise2.then(result=>{
//   console.log(result)
// },reason=>{
//   console.log(reason);
// })
// catch与then类似但是只有一个回调函数
//     只会在rejected时执行 相当于.then(null,()=>{})
//
// promise2.catch(reason=>{

// })
// finally() 无论是reject或resolve都执行回调 但都不会接收到数据 
promise2.finally(() => {
  console.log("nothing stops me");
});





/**
 * promise静态方法
 *  Promise.resolve()创建一个立即完成的promise
 *  Promise.reject(10)创建一个立即拒绝的promise
 * Promise.all() 有一个报错就会返回错误
 * Promise.allSettled() 无论错误与否都返回
 *     [
       { status: 'fulfilled', value: 579 },
       { status: 'rejected', reason: 'hahah' },
       { status: 'fulfilled', value: 46 },
       { status: 'fulfilled', value: 22 }
       ]
    Promise.race() 返回最快的Promise对象
    Promise.any()返回最快的完成的Promise对象 都报错才会catch
 */
function sum(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(a + b);
    }, 1000);
  });
}

// Promise.allSettled().then((r) => console.log(r));

Promise.any([sum(123, 456), sum(12, 34), sum(11, 11)])
  .then((r) => console.log(r))
  .catch((r) => console.log(r));