JavaScript Promise 对象

JavaScript Promise 对象

1、什么是Promise?

1、Promise 是异步编程的一种解决方案,(解决回调地狱)
回调地狱:在js里,在异步js里,回调函数写的太多了,回调套回调。很难凭直觉看懂代码。

var fs = require('fs');
fs.readFile('./views/index.html',  (err, data) => {
    if (err) {   throw err   }
    fs.readFile('./views/main.html', (err, data) => {
        if (err) {   throw err   }
        fs.readFile('./views/update.html', (err, data) => {
            if (err) {  throw err   }
            console.log(data.toString());
        })   
        console.log(data.toString());
    })
    console.log(data.toString());
})

1、从语法上讲,promise是一个对象,
2、从它可以获取异步操作的消息;
3、从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。

  • promise有三种状态:
    pending(等待态), fulfiled(成功态), resolve(结果)
    rejected(失败态);状态一旦改变,就不会再变。
    创造promise实例后,它会立即执行。
2、Promise的then方法和catch方法

1、Promise.prototype.then()方法显然就是Promise的精华。函数声明:p.then(resolve, reject);。
then()方法不是静态方法,需要经由Promise实例对象来调用。
then方法有两个参数,第一个参数是Promise实例对象为Resolved状态时的回调函数,它的参数就是上面Promise构造函数里resolve传递过来的异步操作成功的结果。

第二个参数可选,是Promise实例对象为Rejected状态时的回调函数,它的参数就是上面Promise构造函数里reject传递过来的异步操作失败的信息。

then方法最强大之处在于,它内部可以使用return或throw来实现链式调用。使用return或throw后的返回值是一个新的Promise实例对象(注意,不是原来那个Promise实例对象):

2、Promise.prototype.catch()同样是实例方法,需要经由Promise实例对象来调用,用于Promise实例对象状态为Rejected的后续处理,即异常处理。函数声明:p.catch(reject);

catch方法本质上等价于then(null, reject),参数reject是一个回调函数,它的参数就是Promise对象状态变为Rejected后,传递来的错误信息。

简单来讲:
捕获错误的方法 catch()
解析全部方法 all()
竞赛 race()
生成一个成功的promise resolve()
生成一个失败的promise reject()

3、请求拦截器和响应拦截器中promise体现(axiosRequest)
  • 请求拦截器和响应拦截器 (react)
import React, { Component } from 'react';
import { message } from 'antd';
import Axios from "axios";
import Urls from "./urls.js"; // 接口
import * as querystring from 'querystring'

/* axios请求拦截 */
Axios.interceptors.request.use(
  config => {
    return config;
  },
  err => {
    return Promise.reject(err);
  }
);
/* axios响应拦截 */
Axios.interceptors.response.use(
  res => {
    if (res.headers['content-type'] == 'application/force-download') {
      return res;
    }
    // console.log("res判断前:", res)
    if (res.data.code == 0) {
      // console.log("res判断后:", res)
      // message.warning(res.data && res.data.msg ? res.data.msg : res);
    } else if (res.data.code == -1) {
      message.destroy();
      message.warning(res.data && res.data.msg ? res.data.msg : '登录异常,
      请联系系统管理员');
    } else if (res.data.code == -2) {
      message.destroy();
      message.warning(res.data && res.data.msg ? res.data.msg : '登录异常,
      请联系系统管理员')
      // window.browserRoute.push({ pathname: `/login`, state: { breadArr: [] } })
    }
    return res.data;
  },
  err => {
    if (err.response && err.response.data && err.response.data.code == -1) {
      message.warning("登录验证已失效,请重新登录!")
      window.browserRoute.push({ pathname: `/login`, 
      state: { breadArr: [], title: "登录", urlKey: "login" } })
      window.location.reload(); //方法用于 重新载入当前文档。
    } else if (err.response && err.response.data && err.response.data.code == -2) {// 无权访问
      message.warning(err.response.data.msg);
      return err;
    } else {
      message.destroy();
      message.error(err.msg ? err.msg : err);
    }
    return Promise.reject(err);
  }
);
/* 获取真正的请求数据 */
let getAxiosConfig = function (method, url, data, baseUrl, headers, responseType) {
  let axiosOptions = {};
  axiosOptions.timeout = 1000 * 120;
  axiosOptions.withCredentials = false;
  if (baseUrl) {
    axiosOptions.baseURL = baseUrl;
  } else {
    axiosOptions.baseURL = window.axiosBaseUrl;
  }
  axiosOptions.method = method;
  if (Urls[url]) {
    axiosOptions.url = Urls[url].center + Urls[url].url;
  } else {
    axiosOptions.url = url;
  }
  if (method === "get" && data) {
    axiosOptions.params = data;
  }
  if (method === "post" && data && data.constructor
   && data.constructor.name != "FormData") {
    let dataParse = JSON.parse(JSON.stringify(data))
    for (let key in dataParse) {
      if (typeof dataParse[key] == "string") {
        dataParse[key].trim();
      }
      if ((!dataParse[key]) && (dataParse[key] != 0)) {
        delete dataParse[key]
      }
    }
    if (headers && headers['Content-Type'] 
    && headers['Content-Type'] == "application/json") {
      axiosOptions.data = dataParse
    } else {
      axiosOptions.data = querystring.stringify(dataParse);
    }
  }
  if (data && data.constructor 
  && data.constructor.name === "FormData") {
    console.log(data.getAll("file"))
    axiosOptions.data = data
  }
  let needHeaders = {
    'Content-Type': 'application/x-www-form-urlencoded',
  }
  if (sessionStorage.getItem("REQUSET_TOKEN")) {
    needHeaders["token"] = sessionStorage.getItem("REQUSET_TOKEN")
  }
  if (sessionStorage.getItem("requestTimes")) {
    needHeaders["requestTimes"] = sessionStorage.getItem("requestTimes")
  }
  axiosOptions.headers = { ...needHeaders, ...headers };
  if (responseType) {
    axiosOptions.responseType = responseType;
  }
  return axiosOptions;

};

export const axiosGet = (url, data, baseUrl, headers, responseType) => {
  return new Promise((resolve, reject) => {
    let axiosConfig = getAxiosConfig("get", url, data, baseUrl, 
    headers, responseType);
    Axios(axiosConfig)
      .then(res => {
        // resolve(res);
        if (res.code + "" === "-1") {
          window.browserRoute.push({ pathname: `/login`, 
          state: { breadArr: [], title: "登录", urlKey: "login" } })
          // window.location.reload();
          reject(res.detail);
        } else if (res.code + "" == "0") {
          resolve(res);
        } else if (!res.code && res.data) {
          resolve(res);
        } else if (res.code + "" != "0" && res.code + "" != "-1") {
          reject(res.detail);
        }
      })
      .catch(err => {
        if (err.response && err.response.data 
        && err.response.data.msg) message.error(err.response.data.msg)
        reject(err);
      });
  });
};
export const axiosPost = (url, data, baseUrl, headers) => {
  return new Promise((resolve, reject) => {
    let axiosConfig = getAxiosConfig("post", url, data, baseUrl, headers);
    Axios(axiosConfig)
      .then(res => {
        if (res.code + "" === "-1") {
          window.browserRoute.push({ pathname: `/login`, 
          state: { breadArr: [], title: "登录", urlKey: "login" } });
          // window.location.reload();
          reject(res.detail);
        } else if (res.code + "" == "0") {
          resolve(res);
        } else {
          if (res.code === undefined) {
            resolve(res);
          } else {
            reject(res.detail);
          }
        }
      })
      .catch(err => {
        if (err.response && err.response.data && 
        err.response.data.msg) message.error(err.response.data.msg)
        reject(err);
      });
  });
};

简单介绍:
router.beforeEach 注册一个全局前置守卫:

  • to: Route: 即将要进入的目标 路由对象
  • from: Route: 当前导航正要离开的路由
  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

next的理解–(不带参是放行,带参是重新跳转)

router.beforeEach((to, from, next) => {
  if (to.matched.length ===0) {  //如果未匹配到路由
    from.path? next({ path:from.path}) : next('/');   
    //如果上级也未匹配到路由则跳转主页面,如果上级能匹配到则转上级路由
  } else {
    next();    //如果匹配到正确跳转
  }
});
axios请求拦截器和响应拦截器

1、请求拦截器
请求拦截器的作用是在请求发送前进行一些操作,例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易。

axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么,例如加入token
    .......
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

2、响应拦截器
响应拦截器的作用是在接收到响应后进行一些操作,例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值