axios分步式返回數據接口


對比常規請求與分布式請求:

export function doPackage(params) {return axios.post(package_url,params || {} )}
// 調用封裝函數stepRequset()
export function doPackage (params, stepCallback, lastCallback, timeoutCallback) {
  stepRequest(package_url, params || {}, stepCallback, lastCallback, 3600000, timeoutCallback)
}

分布拉取數據封裝:需要后台配合使用

// import axios from 'axios';
import axios from './axios.js'

function makeUuid () {
  var s = []
  var hexDigits = '0123456789abcdef'
  for (var i = 0; i < 36; i++) {// 0 到 1 之間的一個隨機數*0,然后向下取整四舍五入,ceil(x)是向上舍入
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1) // substr()字符串截取:('dbzhao').substr(3),得到:"hao";('dbzhao').substr(1,3),得到:"bzh";-1是指最后一位
}
// bits 12-15 of the time_hi_and_version field to 0010 s[14] = '4' // bits 6-7 of the clock_seq_hi_and_reserved to 01 s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) s[8] = s[13] = s[18] = s[23] = '-' var uuid = s.join('') return uuid } export const getResponseStepList = (uuid, seqid) => axios.post('/response/steplist', { step_track_uuid: uuid, step_next_seqid: seqid }).then(function (response) { return response }) class TimeoutChecker { // es6定義一個class類 constructor (timeoutMs) { this.timeoutMs = timeoutMs || 3600000 this.restart() } restart () { this.startTime = this.getNowMs() } isTimeout () {// 調用時間是否超時,即大於設置的超時時間 return this.getNowMs() - this.startTime > this.timeoutMs } getNowMs () { return new Date().getTime() } } // export const stepRequest = ( url, // 要封裝調用接口路徑 data, // 封裝調用接口請求數據 stepCallback, // 中間步驟response回調,參數為response json lastCallback, // 調用最后response回調,參數為response json timeoutMs, // 執行超時時間 timeoutCallback // 超時回調,無參數 ) => { let nextSeqid = 0 let isSuccDone = false let timeoutChecker = new TimeoutChecker(timeoutMs) let uuid = makeUuid() data['step_track_uuid'] = uuid const doMainRequest = () => axios({ url: url, method: 'post', data: data, timeout: 3600000 }).then(function (response) { return response }) const handleResponseList = (stepRes) => { for (let response of stepRes.data.response_list) {// es6寫法,只能用於數組let...of...,遍歷value // eslint-disable-next-line stepCallback(eval('(' + response + ')')) //eval()函數會執行字符串內的代碼塊,即:(response),符號:js代碼塊盒子,字母:定義的參數,數字:數值,運算符:正常拼接 } } const handleTimeout = () => { if (timeoutCallback) { let func = timeoutCallback timeoutCallback = null func() } } let interval = setInterval(() => { if (isSuccDone) { clearInterval(interval) handleTimeout() } else { if (timeoutChecker.isTimeout()) { clearInterval(interval) handleTimeout() } else { getResponseStepList(uuid, nextSeqid).then((stepRes) => { if (isSuccDone) { clearInterval(interval) } else { nextSeqid = stepRes.data.next_seqid handleResponseList(stepRes) } }) } } }, 2000) doMainRequest().then(res => { if (!timeoutChecker.isTimeout()) { isSuccDone = true clearInterval(interval) getResponseStepList(uuid, nextSeqid).then((stepRes) => { handleResponseList(stepRes) lastCallback(res.data) }) } else { handleTimeout() } }) }

引用:

import {stepRequest} from 'service/stepreq.js'

實際使用:

    doPackageHandle () {
      Var logMsg = ‘’ // 數組push也行
      var param = {//this.form
        'gitpath': this.form.gitpath,
        'branch': this.form.branch,
        'desc': this.form.desc,
      }

      var stepCallback = (res) => {
        if (res.err_code === '0') {
          // console.log(res,”正在打包中...");
          logMsg += res.info
        } else {
          logMsg = ‘打包失敗’+res.err_desc
        }
      }
      var lastCallback = (res) => {
        if (res.err_code === '0') {
          // console.log(res,"成功”);
          logMsg += res.info
        } else {
          // console.log(res,"失敗”);
          logMsg = ‘打包失敗’+res.err_desc       
        }
      }

      var timeoutCallback = (res) => {
        // console.log(res,”超時");
      }

      doPackage(param, stepCallback, lastCallback, timeoutCallback)
    }                          

二、接口合並請求:

// 合並請求
export async function getFeatureTypeAll () {
  let a = axios.post(get_feature_type)
  let b = axios.post(get_feature_class)
  let res1 = await a
  let res2 = await b
  return {
    val1: res1.data.info || [],
    val2: res2.data.info || []
  }
}

 【對比ES5與ES6對構造函數的定義】:

一、ES5是如何定義構造函數,並實例化后進行調用的:

//函數名和實例化構造名相同且大寫(非強制,但這么寫有助於區分構造函數和普通函數)
function Person(name,age) {
    this.name = name;
    this.age=age;
}
Person.prototype.say = function(){//原型對象特點就是將自身的屬性共享給新對象,即:繼承
    return "我的名字叫" + this.name+"今年"+this.age+"歲了";
}
var obj=new Person("laotie",88);//通過構造函數創建對象,必須使用new 運算符實例化
console.log(obj.say());//使用這個實例化的對象定義的方法say():我的名字叫laotie今年88歲了

這里梳理一下進程:

1.當使用了構造函數,並且new 構造函數(),后台會隱式執行new Object()創建對象;

2.將構造函數的作用域給新對象,(即new Object()創建出的對象),而函數體內的this就代表new Object()出來的對象。

3.執行構造函數的代碼。

4.返回新對象(后台直接返回);

二、ES6通過class關鍵字可以定義類,該關鍵字的出現使得其在對象寫法上更加清晰。

class Person{//定義了一個名字為Person的類
    constructor(name,age){//constructor是一個默認構造方法,實例化后會自動調用,類似vue定義data(),或者react中定義參數
        this.name = name;//this代表的是實例對象
        this.age=age;
    }
    say(){//這是一個類的方法,注意千萬不要加上function
        return "我的名字叫" + this.name+"今年"+this.age+"歲了";
    }
}
var obj=new Person("laotie",88);//可簡單理解為:calss = function + prototype
console.log(obj.say());//我的名字叫laotie今年88歲了

注意:

1.在類中聲明方法的時候,千萬不要給該方法加上function關鍵字

2.方法之間不要用逗號分隔,否則會報錯。 // 定義對象的區分 ,class可以理解為函數體

 

校驗一下通過class構造的實例化對象:

console.log(typeof Person);//function
console.log(Person===Person.prototype.constructor);//true
console.log(Person.prototype);//輸出的結果是一個對象
///////////////////////////////////////////////////////////////
Person.prototype.say=function(){//定義與類中相同名字的方法。成功實現了覆蓋! return "我是來證明的,你叫" + this.name+"今年"+this.age+"歲了"; } var obj=new Person("laotie",88); console.log(obj.say());//我是來證明的,你叫laotie今年88歲了
///////////////////////////////////////////////////////////////
Person.prototype.addFn=function(){ // 再追加一個方法addFn() return "我是通過prototype新增加的方法,名字叫addFn"; } var obj=new Person("laotie",88); console.log(obj.addFn());//我是通過prototype新增加的方法,名字叫addFn

 既然prototype是一個對象,可利用es6對象合並批量添加實例化方法:

Object.assign(Person.prototype,{
    getName:function(){
        return this.name;
    },
    getAge:function(){
        return this.age;
    }
})
var obj=new Person("laotie",88); console.log(obj.getName());//laotie console.log(obj.getAge());//88

需要注意的是定義多個class,內部this是指代本身,因此:

class Desk{
    constructor(){
        this.xixi="我是一只小小小小鳥!哦";
    }
}
class Box{
    constructor(){
       return new Desk();// 這里沒有用this哦,直接new xxx實例化其他的類
    }
}
var obj=new Box();
console.log(obj.xixi);//我是一只小小小小鳥!哦

其次判斷實例化對象是否包含某個原型屬性如何判斷:

console.log(box.hasOwnProperty("xixi"));//true 只有自身存在。且可以等於underfind
console.log("xixi" in box);//true,無法區分自身和原型鏈上的屬性
console.log(Obj.x !== undefined) //點( . )或者方括號( [ ] )不能判斷可以等於undefind對象

class Box{
    constructor(num1,num2){
        this.num1 = num1;
        this.num2=num2;
    }
    sum(){
        return num1+num2;
    }
}
var box=new Box(12,88);
console.log(box.hasOwnProperty("num1"));//true
console.log(box.hasOwnProperty("num2"));//true
console.log(box.hasOwnProperty("sum"));//false
console.log("num1" in box);//true
console.log("num2" in box);//true
console.log("sum" in box);//true
console.log("say" in box);//false

最后分析一下類的所有實例共享一個原型對象,它們的原型都是Person.prototype,所以proto屬性是相等的,即打印對象顯示的__proto__

class Box{
    constructor(num1,num2){
        this.num1 = num1;
        this.num2=num2;
    }
    sum(){
        return num1+num2;
    }
}
//box1與box2都是Box的實例。它們的__proto__都指向Box的prototype
var box1=new Box(12,88);
var box2=new Box(40,60);
console.log(box1.__proto__===box2.__proto__);//true
////////////////////////////////////////////////
box1.__proto__.sub=function(){ //修改原型屬性影響全局原型屬性,不推薦修改 return this.num2-this.num1; } console.log(box1.sub());//76 console.log(box2.sub());//20

class不存在變量提升,所以需要先定義再使用。因為ES6不會把類的聲明提升到代碼頭部,但是ES5就不一樣,ES5存在變量提升,可以先使用,然后再定義。

//ES5可以先使用再定義,存在變量提升
new A();
function A(){

}
//ES6不能先使用再定義,不存在變量提升 會報錯
new B();//B is not defined
class B{

}

 

------------end------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM