Bootstrap

Vue进阶(二十三):Promise 详解

一、前言

意在让异步请求逻辑代码变得干净和直观,让异步请求逻辑代码变得井然有序。

在设计上具有原子性,即只有三种状态:等待()、成功()、失败()。在调用支持的异步方法时,逻辑变得非常简单,在大规模的软件工程开发中具有良好的健壮性。

二、基本语法

要想给一个函数赋予能力,就要先创建一个对象,并将其作为函数值返回。对象要求传入一个函数,并带有和参数。这是两个用于结束等待的函数,对应的状态分别是成功和失败。

function asyncMethod(...args){
    return new Promise((resolve,reject)=>{
        //...
    })
}

将新创建的对象作为异步方法的返回值,所有的状态就可以使用它所提供的方法进行控制了。

三、异步操作

创建 对象后,就可以进行异步操作,并通过和方法来控制的原子状态。

  • 方法控制的是当前对象是否进入成功状态,一旦执行该方法并传入有且只有一个返回值,便会从等待状态()进入成功状态(),也不会再接收任何状态的变。

  • 方法控制的是当前对象是否进入失败阶段,与方法相冋,一旦进入失败阶段就无法再改变。

new Promise((resolve,reject)=>{
    api.call('fetch-data',(err,data)=>{
        if(err) return reject(err)
        resolve(data)
    })
})

其中,在的首层函数作用域中一旦出现语句,对象便会直接进入失败状态,并以语句的抛出值作为错误值进行错误处理。

(new Promise(function() {
    throw new Error ('test')
)))
.catch(err =>console.error(err))

但是,语句并不会使对象进入成功状态,而会使停留在等待状态。所以在对象的执行器()内需要谨慎使用语句来控制代码流程。

四、处理 Promise 状态

与和方法对应,对象有两个用于处理对象状态变化的方法。

这两个方法都会返回一个对象,对象的组合便会成为一个对象链,呈流水线的模式作业。

asyncMethod()
  .then((...args)=>args  /*...*/)
  .catch(err=>console.error(err))

链式处理默认被实现,即或会处理在和中所返回或抛出的值。

  • 如果或中所返回的值是一个对象,则该对象会被加入到的处理链中。

  • 如果或中返回的值并不是一个Promise,则会返回一个己经进入成功状态的对象。

  • 如果或中因为语句而抛出一个错误err,则会返回一个已经进入失败状态的对象。

之所以说对象链呈流水线的模式进行作业,是因为在对象对自身的和响应器的处理中,会对其中返回的对象进行处理。

其内部会将这个新的对象加入到对象链中,并将其暴露出来,使其继续接受新的对象的加入。只有当对象链中的上一个对象进入成功或失畋阶段,下一个对象才会被激活,这就形成了流水线的作业模式。

对象链还有一个十分实用的特性--Promise对象状态具有传递性

如果对象链中的某一环出现错误,对象链便会从出错的环节开始,不断向下传递,直到出现任何一环的对象对错误进行响应为止。

五、高阶方法

5.1 Promise.all(iterable)

该方法可以传入一个可迭代对象(如数组),并返回一个对象,该对象会在当可迭代对象中的所冇对象都进入完成状态(包括成功和失畋)后被激活。

  • 如果可迭代对象中的所有对象都进入了成功状态,那么该方法返回的对象也会进入成功状态,并以一个可迭代对象来承载其中的所有返回值。

  • 如果可迭代对象中的所有对象存在一个进入了失败状态,那么该方法返回的对象也会进入失败状态,并以那个进入失败状态的错误信息作为自己的错误信息。

   Promise.all(promises)
    .then(values=>{
        //...
    })
    .catch(err=>console.error(err))

5.2 Promise.race(iterable)

方法同样也接受一个包含若干个对象的可迭代对象,但不同的是这个方法会监听所有的对象,并等待其中的第一个进入完成状态的对象,一旦有第一个对象进入了完成状态,该方法返回的对象便会根据这第一个完成的对象的状态而改变。

  Promise.race(promises)
    .then(values=>{
        //...
    })
    .catch(err=>console.error(err))

!注意,其他方法仍然会继续执行。

六、拓展阅读