从零开始使用Promise封装请求

2019年8月22日 作者 kee

最近前端小伙伴表示看不懂我封装的api请求,本来想这玩意儿又不常用,而且promise封装没有一定基础确定很难理解,不太想讲。但转念一想,一切讲不清楚,都是因为自身理解不够,真正的掌握,是能够用很简单明了的方式加以阐释的。于是决定试试,便有了这篇文章。

先给出封装的版本

import axios from "axios"
import qs from "qs"
export default (url = "", data = {}, type = "GET", contentType) => {
  return new Promise((resolve, reject) => {
    let requestConfig = {
      method: type,
      url: url,
      headers: {
        "Accept": "application/json",
        "Content-Type": contentType ? contentType : "application/json"
      },
      timeout: 10000
    };

    switch (type.toUpperCase()) {
      case "GET":
        requestConfig.params = data;
        requestConfig.paramsSerializer = params => {
          return qs.stringify(params, { indices: false })
        };
        break;
      case "DELETE":
        requestConfig.params = data;
        break;
      case "POST":
        requestConfig.data = data;
        break;
      case "PUT":
        requestConfig.data = data;
        break;
    }

    if ((type === "POST" || type === "PUT") && contentType !== "multipart/form-data") {
      requestConfig.data = contentType ? qs.stringify(data) : JSON.stringify(data);
    }

    axios(requestConfig).then((resp) => {
      resolve(resp.data);
    }).catch((err) => {
      reject(err);
    })
  });
}

export const prefix = "/v1"
export const userInfo = data => http(`${prefix}/user/info`, data);
export const userAdd = data => http(`${prefix}/user/add`,data,"post");

首先从函数return值说起,如下,外层函数里返回里层函数,里层函数返回一个数值.

// 思考, 怎么取到111?
function demo() {
    return function() {
        return 1111; 
    }
}
console.log(demo())        // ƒ () { return 1111; }
console.log(type demo());  // function
// 很明显了哟,再调一次就行了。也就是第一次调用是拿到里层返回的函数,第二次调用才是执行里层函数

console.log(demo()()) // 111

接下来,说说promise.

// 思考, new 一个promise,并给定返回值,怎么拿到这个值呢?
var a = new Promise((resolve, reject)=> {
    resolve(222);
});
// 基础语法, 就不多说了
a.then(res => {
    console.log(res);   // 222
});

接下来,稍微升华一下,函数里返回promise.

function http() {
    return new Promise((resolve, reject)=> {
        resolve(333);
    });
}
http().then(res => {
    console.log(res);
});
// http()调用后返回的是promise, 所以用.then/.catch回调接着去取值/处理异常

最后,再注意promise里是直接resolve(333),其实呢,promise特性就是一定会有返回值,而且一旦有值了就不会改变。我们完全可以把它换成接口请求,成功了就resolve,失败了就reject。就像下面这样。

function http(url) {
    return new Promise((resolve, reject)=> {
        aixos(url).then(res =>{
            resolve(res);
        }).catch(err => {
            reject(err);
        })
    });
}
http("xxx").then(res => {
    console.log(res);
})

是不是越看越兴奋?如果能全部看懂,恭喜你,基本掌握了。

最后无非就是处理各种请求方式,传参方式,接收方式之类的事,就不多废话了。