浅解Promise

41次阅读

共计 2809 个字符,预计需要花费 8 分钟才能阅读完成。

对于异步的解决方案

Promise

Promise 是 ES6 新增的内置对象,通常使用 Promise 构造函数创建,Promise 实例,解决异步问题。

1.Promise 构造函数 必须 接收一个函数作为参数,我将其称为 executor 函数,executor 函数也可以接收两个参数,resolve 和 reject,它们是两个函数 由 ECMAScript 运行环境提供,无需自己部署。

// 执行 Promise 函数,它返回一个 promise 实例对象
let promise=new Promise ((resolve,reject)=>{console.log(1);
});

当我们使用 new 创建一个构建一个 Promise 实例后,Promise 实例内部的两个属性需要理解。

让我们输出上方的 promise 实例

[[PromiseStatus]]: "pending"
[[PromiseValue]]: undefined

[[PromiseStatus]]: 保存当前 promise 实例的状态, 可能值 pending,resolved,rejected

[[PromiseValue]]:在 promise 未完成状态时,其值为 undefinde, 当 promise 完成后,其值为异步数据,或者错误信息。当执行了 resolve(),[[PromiseValue]]的值就是 resolve()传入 的表达式的值,通常就是是我们需要的值。当我们使用了 reject(),这个值为 reject()的传入值,通常这个值为错误提示

2. 对于 resolve 和 reject,它们的作用是判断对象的状态。并且它们调用时可以接收一个参数。

let promise=new Promise ((resolve,reject)=>{console.log(1);
    resolve('成功');
});

当调用了 resolve 或 reject ,promise 实例的 [[PromiseStatus]] 将发生改变。

现在,让我们更加详细的去了解 Promise

promise 状态

一个 Promise 对象的当前状态 必须 为一下三种状态的一种:Pending(等待状态),Fulfilled(执行状态),Rejected(拒绝状态)

  • Pending:处于 Pending 状态时,promise 可以满足以下条件

​ 可以由 Pending 转为 Fulfilled 或 Rejected,

  • Fulfilled:处于 Fulfilled 状态时,promise 满足以下条件

​ 1. 不可再变为其它状态。

​ 2. 必须有一个不可被改变的值。

  • Rejected

​ 1. 不可再变为其它状态。

​ 2. 必须有一个不可被改变的值。

如何理解 Promise A + 规范中的这三个状态及其规则。

Promise 对象的两个内部属性可以很好帮我们去解释理解。

[[PromiseStatus]] ,[[PromiseValue]]

现在,进行 Promise 第一步,新建一个 Promise 对象,对象两个内部属性被初始化

[[PromiseStatus]] :Pending

[[PromiseValue]]:undefined

此时是规范中的第一种状态,OK,根据规范的 Pending 状态的条件,我们可以去改变其状态。

executor函数在 Promise 对象创建后 立即执行

倘若我们在 executor 函数执行了 resolve()函数, 并且,将一个 表达式 (Expression) 作为其参数传入。此时内部属性值的变化

[[PromiseStatus]]:resolved

[[PromiseValue]]:< 表达式的值 >

此时,Promise 对象的状态有 Pending 变为 Fulfilled. 通俗点说,就是由 等待 变为 成功 。根据 Promise A+ 的 Fulfilled 状态的规范条件,此时, 无论接下来在遇到什么情况,都不会去改变它的状态!,并且 Promise 对象将会有一个值,Yes, 这个值就是我们需要的值,准确的说,它就是那个 传入的表达式的值 ,并且这个值通过 resolve() 函数存入了 [[PromiseValue]] 属性中。我们无法直接去使用它,而是通过 then()去获取

让我们来看个例子

let  p1 = new Promise((res,rej)=>{res((() => {return '成功了';})())
    })
console.log(p1); 
// 输出
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "成功了"

倘若我们在 executor 函数执行了 reject()函数, 并且,将一个 表达式 (Expression) 作为其参数传入。此时内部属性值的变化

let  p2 = new Promise((res,rej)=>{rej((() => {return '失败了';})())
})
console.log(p2);
// promise 对象的两个属性
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: "失败了"

此时,Promise 对象的状态有 Pending 变为 Fulfilled,由 等待 变为 失败 ,根据 Promise A+ 的 Fulfilled 状态的规范条件,此时,无论接下来在遇到什么情况,都不会去改变它的状态!并且 Promise 对象将会有一个值,同样也是那个传入的表达式的值,不过我们将这个值称为 拒因或失败原因

注意:resolvereject 并不会终结 Promise 的 executor 函数的执行

我们已经在 executor 函数中执行了 resolve 或 reject 函数,状态发生改变,内部属性值也发生了改变

现在,该启动 then()方法和 catch()方法了。

then()

它有两个函数作为参数,通常,我们只使用第一个函数来获取 [[PromiseStatus]] 的值为 ”resolved” 的对象的 [[PromiseValue]] 值, 回调函数接收一个参数,此参数就是 [[PromiseValue]] 值

let  p1 = new Promise((res,rej)=>{res((() => {return '成功了';})())
    }).then(data=>{console.log(data) 
    })

注意:then() 方法产生一个微任务,其回调将会被置入上一个宏任务队列后。

cathc()

[[PromiseStatus]] 为 reject 时,调用此方法。

它接收一个函数作为参数,此函数接收一个参数,该参数就是 拒因

let  p2 = new Promise((res,rej)=>{rej((() => {return '失败了';})())
    }).then(data=>{console.log(data) 
    }).catch(error=>console.log(error))

现在大致了解了 Promise 是怎么回事了 Good!

还有注意 :无论如何,在使用 Promise 对象时,加上 catch(),否则你很可能不知道错误到底是出在哪里

正文完
 0