浅析 Promise

前言

刚开始的时候自己对 Promise 的了解不是太深,看到 Promise 就头疼,然后看阮一峰老师的 ES6 标准入门的时候根本看不下去,应该是自己之前的水平太差了,不过最近在看的时候发现基本都能理解了,所以尽可能以一个小白的观点整理一下,希望能帮助更多人理解,这篇文章适合对 Promise 了解的不多,但是想了解的人。如果能耐心读下去的话肯定会对你了解 Promise 有所帮助。

1.1 什么是 Promise

首先我们要知道 Promise 是什么,它可以解决什么问题。

假设有这么一个场景,你需要向后台请求三个字符串,然后需要等到这三个请求的结果都返回然后拼接字符串在进行相关的操作,你该怎么做?

可能你会在 ajax 请求里面的回调里面发起第二个请求,然后第二个请求的回调发起第三个请求,最后在第三个请求的回调里面进行相关操作。是不是想一想就觉得写起来很别扭,而用 Promise 的话就很好解决了


var result = Promise.all([ajax1,ajax2,ajax3]).then(()=>{
    // Todo
})

那么,Promise 到底是什么呢,来看一下定义

Promise 是异步编程的一种解决方案,比起传统的解决方案——回调函数和事件,它更合理且更强大,这一点从上面的例子也可以看出来。

Promise 简单来说就是一个容器,里面放着某个未来才会结束的事件的结果(通常是一个异步操作的结果)。比如说你做数学题的时候遇到了一个难题,然后你把这个难题交给一个大佬,然后你继续做你的事情,然后大佬做出来(或者做不出来)以后将结果告诉你,你再进行相应操作。这个你交给别人做等别人做完返回给你结果的难题就相当于一个 Promise 对象。写成代码如下

let promise = new Promise(function(resolve, reject){
   
   let problem = new Problem(); // 你不会做的题目
   if( solve(problem) )  return resolve('solve'); // 大佬尝试解决这个问题,如果解出来传一个 solve 给你
   else return reject(new Error('not solve')) // 大佬做不出来,传一个 not resolve 给你
});

promise.then(function(value){
   
    // value 就是大佬传过来的值。然后用大佬解出来的结果进行相关操作
}).catch(function(err){
   
    // err 就是大佬解不出来传回的值。假设大佬解不出来进行相关操作
})

它有两个特点,一是它代表的是一个异步的操作,有三种状态:Pending(进行中),Fulfilled(已成功)和 Reject(已失败)。只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都无法改变这种状态,这也是 Promise 的由来,代表无法改变。

二是状态一旦改变就不会再次改变,并且再次调用的时候回立即获得结果。有两种状态改变的可能:从 Pending 变为 Fuilfilled 或者从 Pending 变为 Rejected。状态变化以后就处于 Resolved(已定型)的阶段。这就相当于你让大佬做题,大佬要么不会,要么会,会的话你什么时候问他他都会直接告诉你结果,而不是再去算一遍,不会的话他也是直接告诉你结果,也不会去重新算一遍。

但是 Promise 有两个缺点,一个是一旦新建 Promise 就会立即执行,无法中途取消。
再者,当处于 Pending 状态的时候,无法得知当前进展到哪一个阶段(刚刚开始还是即将完成)。对应到前面的例子的话就是,你把这道题交给大佬了,大佬一定会做,大佬就是喜欢钻研,有题目了一定要得到结果,所以才能称得上是大佬。

还有一个就是如果不设置回调函数, Promise 内部抛出的错误不会反应到外部。

接下来介绍一些 Promise 的基本用法。

1.2 基本用法

直接上代码

let promise = new Promise(function(resolve, reject){
   
    // todo
    if(/*异步操作成功*/){
        resolve(value);
    } else {
        reject(error);
    }
})
// 等同于下面这种方式,因为既然想了解 Promise 的话应该对箭头函数有所了解,所以后面会采用下面这种方式。
let promise = new Promise((resolve, reject)=>{
    // todo
    if(/*异步操作成功*/){
        resolve(value);
    } else {
        reject(error);
    }
})

Promise 构造函数接收一个函数作为参数,该函数的两个参数分别是 resolve 和 reject。它们也是两个函数,有 javascript 引擎提供,不用自己部署

resolve 的作用将 Promise 对象的状态从 “未完成” 变成 “成功”,并将成功时的结果作为参数传出去。

reject 的作用是将 Promise 对象的状态从 “未完成” 变成 “失败”。并将失败的结果作为参数传出去。

Promise 实例生成以后,可以用 then 方法分别指定 Resolved 状态和 Rejected 状态的回调函数。

promise.then(val => {
    // success
},err =>{
    // fail
})

then 方法接收两个回调函数作为参数,第一个回调函数是 Promise 对象状态变为 Fulifilled 时调用,第二个回调函数是 Promise 对象状态变为 Rejected 时调用。第二个参数可选,一般采用 catch 捕捉错误,尽量不使用第二个参数。这两个 函数都接受 Promise 对象传出的值作为参数。

下面是一个简单的例子

var drink = true;
const promise = new Promise((resolve,reject)=>{
    if(drink) return resolve(drink);
    else return reject(new Error('err'));
})

promise.then(val => console.log(val))
.catch(err => console.log(err));

上面的例子创建了一个 Promise 对象,如果 drink 是 true 的话就将 drink 的值传出去,如果是 false 的话,传出 err。

还有一点要注意的是 Promise 对象中的代码会立即执行,看下面的例子

let promise = new Promise((resolve,reject)&
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值