javascript 异步请求封装成同步请求

此方法是异步请求封装成同步请求,加上token验证,环境试用微信小程序,可以修改文件中的ajax,进行封装自己的,比如用axios等

成功码采用标准的 200 到 300 和304 ,需要可以自行修改

同步任务接入之后,每个任务会进行token的验证,每个任务之间都是同步请求,包括token

/**
 *  同步流请求
 *  token验证每个接口
 *  柯里化添加同步任务
 *  resolve返回res,cb
 *  reject 返回res,cb
 *  通过任务中断测试
 *  通过成功失败回调函数测试
 *
 *  任务流 任务接入柯里化函数 currying(()=>{})              -->
 *  开始执行 currying() 进入g函数循环同步执行异步方法        -->
 *  执行异步方法 调用 rp 函数 封装 return new promise       -->
 *  rp 函数 执行判断 token 状态 进行处理
 */

const regeneratorRuntime = require(‘./regenerator-runtime/runtime.js‘) //runtime类
const errorMessage = ‘服务繁忙,稍后再试‘ //公共提示
const successMessage = ‘完成‘ //公共提示

class SuperClass {
  constructor() {
    Object.assign(this, {})
    //等待执行的接口
    this.wait = []
  }

  //Promise 请求接口
  rp(opts, skipToken = false) {
    const _t = this,
      data = opts.data || {}
    //小程序标识
    data.source = opts.sourceFlag ? data.source : 1;

    //请求信息
    console.group(`请求接口---${opts.url}`);
    console.log(‘接口信息‘, {
      opts,
      skipToken
    })
    console.groupEnd();

    return new Promise(function(resolve, reject) {

      opts.header = {
        "Content-Type": "application/json;charset=utf-8",
        //不需要走token的接口
        Authorization: !!opts.skipToken ? ‘‘ : (wx.getStorageSync(‘token‘) || ‘‘)
      }

      wx.request({
        url: ‘域名‘ + opts.url,
        data: data,
        header: opts.header,
        method: opts.method,
        dataType: ‘json‘,
        responseType: ‘text‘,
        success: function(res) {
          const {
            data
          } = res

          //成功 400为token失效 处理token失效问题 内层函数收集token失败码归并处理
          if (data && (_t.successCode({
              code: data.code
            }) || data.code == 400)) {
            resolve(data)
          } else {
            //其他不可预测为失败
            reject(data)
          }
        },
        fail: function(res) {
          reject(res.data)
        },
        complete: function(res) {
          //完成停止加载
          wx.hideToast()
          opts.complete && opts.complete(res.data)
        }
      })
    })
  }

  //为空参数抛异常
  paramNoNull() {
    throw new Error(‘Missing parameter‘)
  }

  // g函数
  async g() {
    let _t = this,
      //中断任务
      isbreak = !1

    for (let [i, v] of _t.wait.entries()) {
      const r = await v().catch((res) => {
        //收集 所有的错误 统一执行 提示 或者错误回调
        const {
          cb,
          message
        } = res

        //同步流中断
        _t.clearWait()
        isbreak = !0;
        //没有回调函数执行错误提示
        ‘cb‘ in res ? cb() : (wx.factory._toast(message || errorMessage))
      })

      //任务执行成功
      if (!!r && r.constructor === Object && !!Object.keys(r).length) {
        const {
          res: {
            code,
            data,
            message
          },
          cb
        } = r

        //外层函数只处理成功状态
        if (_t.successCode({
            code
          })) {
          !!cb && cb()

          //同步流执行完成
          if ((i + 1) == _t.wait.length) {
            _t.clearWait()
            wx.factory._toast(message || successMessage)
          }
        } else {
          //同步流中断
          _t.clearWait()
          isbreak = !0

          wx.factory._toast(message || errorMessage)
        }
      }

      if (!!isbreak) {
        break
      }
    }
  }

  //清空任务
  clearWait() {
    this.wait = []
  }

  //柯里化
  currying() {
    const _t = this
    return (function(arg) {
      if (arg.length === 0) {
        _t.g()
      } else {
        [].push.apply(_t.wait, arg);
      }
    })(arguments)
  }

  //成功码
  successCode({
    code = 404
  }) {
    return (code >= 200 && code < 300) || code == 304
  }
}

//超类,实现多继承
const decorator = Sup => class extends Sup {
  constructor(...args) {
    super(...args)
  }

  //获取token接口
  greatetoken(opts) {
    let codeOPts = JSON.parse(JSON.stringify(opts));
    codeOPts.url = `/getToken`
    codeOPts.method = `POST`
    codeOPts.data = {
      appIds: "xx",
      userId: 5
    }
    return super.rp(codeOPts, true).then((res) => {
      const {
        code,
        data
      } = res
      if (super.successCode({
          code: cb.code
        })) {
        if (!!data && !!data.token) {
          //全局token存储 方式为 storage
          wx.setStorageSync(‘token‘, data.token)
        } else {
          wx.factory._toast(‘获取token失败‘)
        }
      } else {
        wx.factory._toast(‘获取token失败‘)
      }
    }).catch(() => {
      wx.factory._toast(‘获取token失败‘)
    })
  }

  /**
   * 接口公共类
   * 同步请求返回 Promise
   * 请求 token 为前提,为空 过期重新请求
   */
  async send(opts) {
    const token = wx.getStorageSync(‘token‘),
      sendFun = (opts) => {

        //转化http请求 catch捕获promise的reject 展示接口级别错误 只做console打印 其他操作流入g函数(回调,提示)
        return super.rp(opts).catch(res => {

          //此处显示rp reject 报错
          console.group(`%c请求接口---${opts.url}---报错`, ‘color:red;‘);
          console.log(` --> 参数`, {
            data: opts.data
          });
          console.log(` --> 返回值`, {
            res
          });
          console.groupEnd();

          //把错误信息传到 g 函数的catch里面
          opts.fail && opts.fail(res)
        })
      },
      successFun = async(opts) => {
        const cb = await sendFun(opts)

        //把成功信息传到g函数里面
        super.successCode({
          code: cb.code
        }) && opts.success && opts.success(cb)
      }

    if (!opts.skipToken) { //需要token请求
      if (!token) { //token为空 直接发起token请求
        await this.greatetoken(opts)
        await successFun(opts)
      } else {
        const cb = await sendFun(opts)
        if (!!cb) {

          //400 token过期  只有在存在token的情况下才会有时效的情况 归并处理
          if (cb.code == 400) {
            await this.greatetoken(opts)
            await successFun(opts)
          } else {
            //把成功信息传到g函数里面
            super.successCode({
              code: cb.code
            }) && opts.success && opts.success(cb)
          }
        }
      }
    } else {
      await successFun(opts)
    }
  }

  post(opts) {
    opts.method = "POST";
    this.send(opts)
  }

  get(opts) {
    opts.method = "GET";
    this.send(opts);
  }
}

class Http extends decorator(SuperClass) { //子类
  constructor() { //继承参数
    super()
  }
}

export default new Http

引入方式,全局调用

import Http from ‘./public/js/request‘
wx.http = Http

调用执行,可用bind函数进行传参

success返回为成功的,code值流入任务进行code值判断区分 resolve

fail返回失败 reject

complete执行的为方法

Page({
   onLoad(){
     wx.http.currying(this.a.bind(this, {
      a: 1
    }))
    //进行传参bind
    wx.http.currying(this.b)
    wx.http.currying()
  },
  a() {
    const _t = this
    wx.factory._toast(‘加载a信息中...‘, 6000)
    return new Promise((resolve, reject) => {
      wx.http.post({
        url: ‘a‘,
        data: {
          "params": {
            id:33
          }
        },
        success(res) {
          resolve({
            res,            cb()=>{}
          })
        },
        fail(res) {
          reject({
            res,            cb()=>{}
          })
        }
      })
    })
  },
  b() {
    const _t = this
    wx.factory._toast(‘加载b信息中...‘, 6000)
    return new Promise((resolve, reject) => {
      wx.http.post({
        url: ‘b‘,
        data: {
          id:33
        },
        success(res) {
          resolve({
            res
          })
        },
        fail(res) {
          reject({
            res
          })
        }
      })
    })
  }
})

原文地址:https://www.cnblogs.com/lmyt/p/11323640.html

时间: 2024-10-08 06:53:16

javascript 异步请求封装成同步请求的相关文章

利用meta标签将http请求换成https请求

最近网站升级为https之后,为了防止一些http文件没有修改而引起的问题,可以加一个meta标签: <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> 说明:有一定兼容性问题. 原文地址:https://www.cnblogs.com/leaf930814/p/8961778.html

Ajax异步&amp;同步请求

一.简介 Ajax请求最重要的问题是代码执行的顺序.最长遇到的问题是,我们定义一个变量接收ajax异步请求的返回结果,后续代码使用,然而后续代码在使用时该变量为初始值,始终得不到想要的结果!!! 二.示例 // 同步 var email = "[email protected]"; console.log(1); jQuery.ajax({ url: "/invite/sendEmailAjax.pt", type: "post", dataTy

ios中的ASIHTTPRequest的同步请求和异步请求

1.首先加入ASI开源库 2. WebImageView.h #import <UIKit/UIKit.h> #import "ASIHTTPRequest.h" @interface WebImageView :UIImageView<ASIHTTPRequestDelegate> - (void)setImageURL:(NSURL *)url; @end WebImageView.m #import "WebImageView.h" #

F. 异步同步请求

一,open方法第三个参数不设置,默认为true,即异步 二,使用同步请求的时机 三, 四, 五, 六, 原文地址:https://www.cnblogs.com/youyuanjuyou/p/8256866.html

async: false 实现AJAX同步请求 ( $.ajax同步/异步(async:false/true) )

虽然说ajax用来执行异步请求的比较多,但有时还是存在需要同步执行的情况的. 比如:我需要通过ajax取执行请求以返回一个值,这个值在ajax后面是需要使用到的,这时就不能用异步请求了.这时候就需要使用到async这个属性了. async:true,(默认),异步方式,$.Ajax执行后,会继续执行ajax后面的脚本,直到服务器端返回数据后,触发$.Ajax里的success方法,这时候执行的是两个线程. async:false,同步方式,所有的请求均为同步请求,在没有返回值之前,同步请求将锁住

原生与jQuery封装的ajax请求数据及状态码

原生Ajax 请求数据 btn.addEventListener('click',function(){ if(window.XMLHttpRequest){ var xhr = new window.XMLHttpRequest(); }else{ //兼容IE浏览器 var xhr = new ActiveXObject('Microsoft.XMLHTTP'); } //请求方式get/post //请求URL //ture 异步请求:false 同步请求 xhr.open('get','

2018-09-01HTTP响应+HTTP请求封装+HTTP响应封装+服务器部署步骤+DynamicWeb工程创建

HTTP协议: HTTP,超文本传输协议(HyperText Transfer Protocol)是互联网上应用最为广泛的 一种网络协议!所有的WWW文件都必须遵守这个标准,设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法! Http协议由HTTP请求和HTTP响应组成,当在浏览器中输入网址访问某个网站时,  你的浏览器会将你的请求封装成一个Http请求发送给服务器站点,服务器接收到请求后会组织响应数据封装成一个HTTP响应返回给浏览器,即没有请求就没有响应! 1:请求行 请求方

iOS项目开发实战——使用同步请求获取网页源码

网络请求一般分为同步请求和异步请求,同步请求假设訪问时间过长,会造成界面卡死状态,用户体验不是非常好.可是请求速度较快的话,也能够考虑使用同步訪问.如今先来学习同步訪问. (1)在viewDidLoad()方法中实现例如以下代码: override func viewDidLoad() { super.viewDidLoad() var data = NSURLConnection.sendSynchronousRequest(NSURLRequest(URL: NSURL(string: "h

iOS项目开发实战——使用同步请求获取网页源代码

网络请求一般分为同步请求和异步请求,同步请求如果访问时间过长,会造成界面卡死状态,用户体验不是很好.但是请求速度较快的话,也可以考虑使用同步访问.现在先来学习同步访问. (1)在viewDidLoad()方法中实现如下代码: override func viewDidLoad() { super.viewDidLoad() var data = NSURLConnection.sendSynchronousRequest(NSURLRequest(URL: NSURL(string: "http