第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

ES6-10 入門教程

首頁 慕課教程 ES6-10 入門教程 ES6-10 入門教程 ES6 實(shí)戰(zhàn)2-封裝請(qǐng)求

ES6 + 實(shí)戰(zhàn) 2 - 封裝請(qǐng)求

1. 前言

在學(xué)習(xí) Promise 相關(guān)小節(jié)時(shí)我們已經(jīng)了解了 Promise 的基本用法和 Promise A + 規(guī)范,那么在實(shí)際項(xiàng)目中我們應(yīng)該怎么去使用 Promise 來提高我們的效率,并且可以通過 Promise 去封裝一些異步方法,讓我們?cè)谑褂眠^程中更加得心應(yīng)手。

本節(jié)我們將模擬一個(gè)真實(shí)的生產(chǎn)環(huán)境來對(duì)前端開發(fā)中最常見也是最重要的數(shù)據(jù)請(qǐng)求進(jìn)行封裝。通過使用封裝 Promise 請(qǐng)求來學(xué)習(xí) Promise 在實(shí)際項(xiàng)目當(dāng)中是如何使用的。

2. 環(huán)境搭建

工欲善其事,必先利其器,在我們進(jìn)入本節(jié)的學(xué)習(xí)前,我們需要先搭建我們的開發(fā)環(huán)境,在實(shí)際的項(xiàng)目中也是必須的。本節(jié)使用的是 Vue 腳手架生成的項(xiàng)目,不了解 Vue 的同學(xué)可以先去學(xué)習(xí)一下。在 vue.config.js 配置中,對(duì) ajax 請(qǐng)求進(jìn)行了 mock 操作,mock 的邏輯在 mock.config.js 文件中,mock 的結(jié)果在 mock 文件夾下對(duì)應(yīng)的 json。

這樣的配置在本節(jié)中就可以基本模擬真實(shí)的數(shù)據(jù)請(qǐng)求過程了,本節(jié)的源碼在 GitHub 上。

3. 封裝 ajax 請(qǐng)求

ajax 是前端用于發(fā)送接口請(qǐng)求的技術(shù),它是異步的,需要等待結(jié)果返回后執(zhí)行

在發(fā)送 ajax 請(qǐng)求時(shí),我們可能會(huì)這樣去寫。

ajax({
  url: '',
  method: '',
  data: {},
  params: {},
  success: function (res) {},
  error: function (err) {}
})
  • url: 接口請(qǐng)求地址;
  • method: 接口請(qǐng)求方法,如:get、post 等;
  • data: 請(qǐng)求時(shí)使用 body 傳輸?shù)臄?shù)據(jù),一般用于 post 請(qǐng)求中;
  • params: 請(qǐng)求時(shí)使用 url 傳遞的數(shù)據(jù),一般用于 get 請(qǐng)求中;
  • success: 接口請(qǐng)求成功時(shí)的回調(diào),參數(shù)為接口成功的返回值;
  • error: 接口請(qǐng)求失敗時(shí)的回調(diào),參數(shù)為拋出異常時(shí)的調(diào)用棧等信息。

XMLHttpRequest 是瀏覽器提供的對(duì)象,用于進(jìn)行后臺(tái)與服務(wù)端的數(shù)據(jù)進(jìn)行交互

實(shí)現(xiàn) ajax

function ajax(options) {
  const { url, method, data, params, success, error } = options;
  const xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function () {
    // readyState為4的時(shí)候已接收完畢
    if (xhr.readyState === 4) {
      // 狀態(tài)碼200表示成功
      if (xhr.status === 200) {
        console.log(xhr.responseText);
        success.call(this, xhr.responseText);
      } else {
        console.log(xhr.status);
        error.call(this, xhr.status)
      }
    }
  };

  // get 請(qǐng)求
  if (method === 'get' || method === 'GET') {
    if (typeof params === 'object') {
      // params拆解成字符串
      params = Object.keys(params).map(function (key) {
        return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
      }).join('&');
    }
    url = params ? `${url}?${params}` : url;
    xhr.open(method, url, true);
    xhr.send();
  }

  // post 請(qǐng)求
  if (method === 'post' || method === 'POST') {
    xhr.open(method, url, true);
    xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
    xhr.send(JSON.stringify(params));
  }
}

使用 promise 進(jìn)行封裝

function ajax(url, method, params) {
  return new Promise((resolve, reject) => {
    // 創(chuàng)建XMLHttpRequest對(duì)象
    const xhr = new XMLHttpRequest();
    // 狀態(tài)改變時(shí)的回調(diào)
    xhr.onreadystatechange = function () {
      // readyState為4的時(shí)候已接收完畢
      if (xhr.readyState === 4) {
        // 狀態(tài)碼200表示成功
        if (xhr.status === 200) {
          resolve(xhr.responseText);
        } else {
          reject(xhr.status);
        }
      }
    };
    // ...
  });
}

4. axios 庫封裝

在真實(shí)的項(xiàng)目中會(huì)經(jīng)常使用到 axios 這樣的 ajax 請(qǐng)求的庫,雖然可以直接使用,但是往往業(yè)務(wù)中會(huì)有很多接口請(qǐng)求的地方,而這么多的請(qǐng)求有些固定不變的,每個(gè)接口在請(qǐng)求時(shí)都需要,如:token,baseURL,timeout 等等,針對(duì)這樣的場景,我們可以對(duì) axios 庫進(jìn)行二次業(yè)務(wù)封裝。對(duì)于接口不同的返回結(jié)果我們希望有一個(gè)全局的提示框,這里我們使用 element-ui 組件庫搭配使用。封裝后的代碼如下:

import axios from 'axios';
import { baseURL } from '@/config'

class Http {
    constructor(baseUrl) {
        this.baseURL = baseURL;
        this.timeout = 3000;
    }
    setInterceptor(instance) {
        instance.interceptors.request.use(config => {
            return config;
        });
        instance.interceptors.response.use(res => {
            if (res.status == 200) {
                return Promise.resolve(res.data);
            } else {
                return Promise.reject(res);
            }
        }, err => {
            return Promise.reject(err);
        });
    }
    mergeOptions(options) {
        return {
            baseURL: this.baseURL,
            timeout: this.timeout,
            ...options
        }
    }
    request(options) {
        const instance = axios.create();
        const opts = this.mergeOptions(options);
        this.setInterceptor(instance);
        return instance(opts);
    }
    get(url, config = {}) {
        return this.request({
            method: 'get',
            url: url,
            ...config
        })
    }
    post(url, data) {
        return this.request({
            method: 'post',
            url,
            data
        })
    }
}
export default new Http;

5. 小結(jié)

本節(jié)我們通過真實(shí)的業(yè)務(wù)場景觸發(fā),對(duì)原生的 ajax 請(qǐng)求做了 promise 封裝,最后我們對(duì)真實(shí)的業(yè)務(wù)場景使用 axios 對(duì)業(yè)務(wù)二次封裝,這樣更好地復(fù)用業(yè)務(wù)邏輯,統(tǒng)一增加不同返回結(jié)果的提示。