js 异步&Promise

js 异步&Promise

主任务任务队列

主任务只有一个

主任务运行结束后,会从任务队列中寻找任务执行

主(同步)任务、promise、宏任务、微任务

setTimeout():属于宏任务。

console.log():属于主任务。

new Promise():里面的

resolve => {
resolve();//或reject()
console.log(“promise”);
}:属于主任务。

.then(()=>{},()=>{}):属于微任务,只有当resolve、reject有一执行时,.then()才会执行。

**任务执行顺序:**主任务、微任务、宏任务。

微任务包括 process.nextTickpromiseObject.observeMutationObserver

宏任务包括 scriptsetTimeoutsetIntervalsetImmediateI/OUI rendering

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HJ1TpKhr-1585212783289)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\1585037163946.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1KiKRoq0-1585212783293)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\1585037430994.png)]

Promise.then()的返回值也是一个Promise对象

1.前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。console.log®就需要等到上一个Promise状态返回。

let p1 = new Promise((resolve, reject) => {
      // reject("fail");
      resolve("fulfilled");
    })
      .then(
        value => {
          // return "houdunren";
  		 console.log(value)
          return new Promise((resolve, reject) => {
            // resolve("解决了");
            setTimeout(() => {
              reject("处理失败");
            }, 3000);
          }).then(null, r => {
            console.log(r)
            return new Promise((resolve, reject) => {
              reject("失败了。。。。");
            });
          });
        },
        reason => console.log("erorr" + reason)
      )
      .then(
        value => {
          console.log("成功:" + value);
        },
        reason => console.log("error" + reason)
      );

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SJ6CkXfY-1585212783297)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\1585052210938.png)]

2.当then()方法没有返回Promise的状态,就默认是resolve()

let p1 = new Promise((resolve, reject) => {
      // resolve("fulfilled");
      reject("rejected");
    });
    let p2 = p1
      .then(
        value => console.log(value),
        reason => console.log(reason)
      )
      .then(
        a => console.log("成功"),
        b => console.log(b)
      );

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m3ay5l8k-1585212783298)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\1585052058259.png)]

其它类型的Promise封装

下面展示了三种类型的封装:只要你返回的对象里面有Promise或then里面包含(resolve,reject),且里面返回了状态,就可以。

let p1 = new Promise((resolve, reject) => {
      resolve("fulfilled");
    })
      .then(
        value => {
          // class Hd {
          //   then(resolve, reject) {
          //     setTimeout(() => {
          //       resolve("这是对象");
          //     }, 2000);
          //   }
          // }
          // return new Hd()
          //======================
          // return then(resolve,reject){
          //   resolve("成功")
          // }
          //======================
          return class {
            static then(resolve, reject) {
              // resolve("这是一个静态方法");
              reject("失败");
            }
          };
        },
        reason => {}
      )
      .then(
        value => {
          console.log(value);
        },
        reason => {
          console.log(reason);
        }
      );

Promise.prototype.catch()

catch()其实与then()的第二个参数功能类似

p.then((val) => console.log('fulfilled:', val))
  .catch((err) => console.log('rejected', err));

// 等同于
p.then((val) => console.log('fulfilled:', val))
  .then(null, (err) => console.log("rejected:", err));

比较下面两种写法,可以发现reject方法的作用,等同于抛出错误

// 写法一
const promise = new Promise(function(resolve, reject) {
  try {
    throw new Error('test');
  } catch(e) {
    reject(e);
  }
});
//也可以用promise.then(null,reason=>{console.log(reason)})
promise.catch(function(error) {
  console.log(error);
});

// 写法二
const promise = new Promise(function(resolve, reject) {
  reject(new Error('test'));
});
promise.catch(function(error) {
  console.log(error);
});

一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

// bad
promise
  .then(function(data) {
    // success
  }, function(err) {
    // error
  });

// good
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。

Promise对象里面的错误,不管有没有then()第二个参数或catch接受,会报错但不会影响后面的代码执行,其实也好理解,仅仅就是没有捕获错误,并不会影响代码执行。

待更新…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值