JS-01-Promise使用

59 阅读2分钟

一、概述

自己对Promise的理解仅仅停留在他是一个异步请求后台接口的处理方式上,突然看到有些没有请求后台接口的函数也使用到了Promise,顿时感到非常疑惑,于是强补下这方面的知识。

二、主要使用方法

2.1 异步请求后台接口的后续处理

此种方式是我项目中最常用使用到Promise的场景了,伪代码如下:

// 定义一个页面初始化的方法
function initPage() {
  let params = {
    param1: 'data1',
    param2: 'data2'
  }
  httpPost('http://www.test.com/', params)
    .then(data => {
      console.log(data)
    }).catch(error => {
      console.log(error)
    })
}

其中httpPost的定义如下,基于axios进行了简单的封装:

function httpPost(url, data) {
  return new Promise((resolve, reject) => {
    axios.post(url, data)
      .then((res)=>{
        resolve(res)
      }).catch(error => {
        reject(error)
      })
  })
}

两个代码片段中,代码片段1的then对应代码片段2中的resolve,catch对应reject。

这里有一个经验,定义一个Promise的对象的时候,函数返回它。如上httpPost中就返回了一个Promise对象。

2.2 优雅的写法-链式操作

2.2.1 传统写法

在Promise出现之前,处理两个异步操作可能如下:

// 假设 doSomething1和doSomething2是异步的方法
// 再doSomething1之后才能开始doSomething2的操作
doSomething1(function(callbackData){
  console.log('process doSometing1 callback')
  doSomething2(function(callbackData) {
    console.log('process doSometing2 callback')
  }
})

如果有很多个数据请求都需要依赖前面一个请求,这种嵌套就很多,在我经历的项目中,可能有5-6层这种嵌套调用,缩进就很多,看起来不太优雅。

2.2.2 链式写法

下面使用两个setTimeout来模拟异步,体验下链式操作。

// 2秒后执行
function doSomething1() {
  return new Promise((resolve, reject) => {
    setTimeout(()=> {
      console.log('doSomething1')
      resolve('doSomething1 complete')
    }, 2000)
  })
}
// 0.2秒收执行
function doSomething2() {
  return new Promise((resolve, reject) => {
    setTimeout(()=> {
      console.log('doSomething2')
      resolve('doSomething2 complete')
    }, 200)
  })
}

doSomething1().then(res=>{
  return doSomething2()
})

从执行结果来看,先完成了doSomething1,再执行doSomething2。

image.png

2.3 处理推迟

Promise的resolve和reject方法推迟了对函数请求的结果处理,当函数实际被调用的时候,再根据内部定义的返回进行对应的处理。从我自己的项目经验来看,Promise一般是在封装在基础功能里面,不涉及业务。

三、总结

Promise目前项目中主要用于封装基础组件,对于一些通用的业务组件,通过这次复习,也会逐渐尝试使用,减少冗余代码。