Promise及其应用

Promise及其应用

promise与异步编程

Promise是异步编程的一种解决方案,比传统方法(回调函数与事件)更合理、更强大。

promise作用

  1. promise是一个容器,里面保存着未来才会结束的事情的结果,这个事情通常是一个异步操作,例如:老师在课堂上布置了考试内容,考试时间20分钟,20分钟以后老师发下答案,让同学们在课后核对答案,老师则继续讲课,promise就相当于学生课后核对答案这个事情的结果,与主线程(老师讲课)毫不相干。
  2. 在语法上,promise是一个对象,可以获取异步操作的消息。
  3. promise提供统一的API,各种异步操作都可以用同样的方法进行处理。

promise特点

  1. 对象状态不受外界影响。 Promise对象代表一个异步操作,有三种状态:
  • pending(进行中)
  • fulfilled(已成功)
  • rejected(已失败)

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

  1. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。
  • 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

promise缺点

  • 无法取消promise,一旦新建它就会立即执行,无法中途取消
  • 如果不设置回调函数,promise内部抛出的错误不会反应到外部
  • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

promise基本用法

示例

console.log("a");
setTimeout(() => console.log("b"));
let p = new Promise((resolve, reject) => {
  resolve();
  console.log("c");
}).then(() => {
  console.log("d");
});
console.log("e");

复制代码

首先此段代码会输出a。来到了seTimeout(),seTimeout定时器要等时间到才会触发事件进入宏任务,所以b输出会在最后执行。resolve作为一个执行器函数,作为同步代码执行,会立即执行,所以c的输出会放在宏任务,相比then,会先执行,输出c。随后then方法不会立即输出d,它会将回调注册到promise的fulfilled状态,和setimeout相似,fulfilled在then里面会放在微任务队列,后面执行。所以此时要等脚本执行完,先输出e,再输出d。等所有宏任务执行完以后,setimeout函数触发事件进入宏任务,最后输出b。所以此上函数输出顺序为acedb。

resolve()与reject()

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。

const promise = new Promise(function (resolve, reject) {
	//...do something
	if (/*异步操作成功*/) {
		resolve(value);
	} else {
		reject(error);
	}
复制代码
  • resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 fulfilled),在异步操作成功时调用,并将异步操作成功的结果,作为参数传递出去。
  • reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

then()方法

promise实例生成后,可以使用then方法分别指定resolved状态和rejected状态的回调函数。

promise.then(function(value){
	//value
}, function(error){
	//error
});
复制代码

then方法可以接受两个回调函数作为参数

  • 第一个回调函数:promise对象的状态变为fulfilled时调用。
  • 第二个回调函数:promise对象的状态变为rejected时调用。
  • 注意第二个函数可选,不一定非要提供。

注: promise新建以后会立即执行,首先输出的是promise,then方法指定的回调函数将在当前脚本所有同步任务执行完才会执行。

resolve()与reject()方法

promise.resolved()方法

  • 返回一个具有定值的promise对象
  • 如果传入的参数是一个promise实例,则将该实例直接返回;否则会创建一个新的promise对象,将传入的参数作为promise对象的fulfilled值。

promise.reject()方法

用于返回一个rejected状态的promise实例,但是不常用。

原因:状态已经被置为rejected,rejected函数只能用onrejected函数执行,所以只能用catch。

Promise.reject(new Error("a error"))
.catch((err)=>{
    console.log(err.message);
    return "done";
})
.then((value)=>{
    console.log(value);
});
复制代码

注:rejected和resolve为构造函数方法,catch和then为实例方法 调用resolve和reject之后,promise的使命已经完成,后续操作都会放进then方法里面。

链式调用

promise实例可以链式的使用then()调用,并且可以一直调用。

let promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    let t = true;
    if (t) {
      resolve("success");
    } else {
      reject("failed");
    }
  }, 1000);
});
promise1.then((r) => {
    console.log(r);
    return r + "1";
  }).then((r) => {
    console.log(r);
    return r + "2";
  }).then((r) => {
    console.log(r);
  });
复制代码

以上代码then方法的调用中,每一个r都依赖于上一个r。

多个Promise一起调用

Promis.all()

当需要将多个Promise任务一起执行时,可以使用Promise.all( )方法。 Promise.all( )执行完毕的结果是所有输出结果的所组成的数组。

  var p1 = new Promise((res, rej) => {
    setTimeout(() => {
      res("p1");
    }, 1000);
  });
  var p2 = new Promise((res, rej) => {
    setTimeout(() => {
      res("p2");
    }, 2000);
  });
  var p3 = new Promise((res, rej) => {
    setTimeout(() => {
      res("p3");
    }, 3000);
  });
  Promise.all([p1, p2, p3]).then((r) => {
      console.log(r);
    }).catch((err) => console.log(err.messsage));
复制代码

注意:只要有一个失败,也就是说只要有一个rej,都会返回失败,返回失败则执行catch。 如果执行成功,则是按照数组的顺序输出,而不是按照时间长短来输出。

Promise.race(iterable)方法(谁先完成)

以下方示例

  • iterable为包含了多个promise数组。
  • 该方法返回一个 promise。
  • 一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝。

执行此代码时promise3的错误会直接抛给浏览器,因为跑的最快的发生错误,catch会执行。但是如果执行到then时的结果为true,但是也会报错,因为promise3的错误未处理。

async函数

async作用与用法

ES2017引入了async函数。

 async function testAsync() {
    return "hello async";
  }
  console.log(testAsync());
  testAsync().then((r) => {
    console.log(r);
  });
复制代码

async函数返回的Promise对象会运行执行(resolve)异步函数的返回结果,会把返回值传递给Promise.resolve(),如果异步函数抛出异常的话会运行拒绝(reject)。

await指令

await作用与用法

异步函数可以包含await指令,该指令会暂停异步函数的执行,并等待Promise执行,然后继续执行异步函数,并返回结果。 示例:

 function testAsync() {
    //只有返回值、没有返回Promise的函数
    return "hello async";
  }
  function testPromise() {
    //返回Promise的函数
    return new Promise((resolve) => {
      resolve("hello Promise");
    });
  }
  async function test() {
    var Async_1 = await testAsync();
    var Promise_1 = await testPromise().then();
    console.log(Async_1); 
    console.log(Promise_1); 
  }
  test();
复制代码

综合async、await分析

async 函数是使用async关键字声明的函数。async 函数是 AsyncFunction 构造函数的实例,并且其中允许使用 await 关键字。async 和 await 关键字让我们可以用一种更简洁的方式写出基于 Promise的异步行为,而无需刻意地链式调用 promise

作者:菜菜的小霞
链接:https://juejin.cn/post/7219567168315490364
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值