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------------