Skip to content

axios和fetch区别

二者都用来发送ajax请求,实现局部更新,axios是基于xhr的,fetch是原生支持的。

axios的拦截器是什么?有什么用?

interceptors.request可以做身份验证

interceptors.response可以做error日志处理,统一返回格式(res.data和res.data.data统一为res.data)

JS
const instance = axios.create({
    baseURL: 'https://api.example.com',
    timeout: 1000,
    headers: {
        'Content-Type': 'application/json'
    }
})


// 类似express中的app.use,可以做身份验证
instance.interceptors.request.use(
    function(config){
        const token=localStorage.getItem('token')
        if(token){
            config.headers.Authorization=`Bearer ${token}`
        }
        return config
    }
    function(error){
    	return Promise.reject(error)
	}
)

// 可以用来统一处理error日志,而不是在每个catch中处理
axios.interceptors.response.use(
  response => {
    // 处理成功的响应
    console.log('Response received:', response);
    // 例如统一处理数据格式
    if (response.data && response.data.data) {
      return response.data.data;
    }
    return response;
  },
  error => {
    // 处理错误的响应
    console.error('Error response:', error);
    // 例如统一处理错误信息
    if (error.response) {
      switch (error.response.status) {
        case 401:
          // 处理未授权错误
          console.error('Unauthorized');
          break;
        case 500:
          // 处理服务器错误
          console.error('Server error');
          break;
        default:
          console.error('Error status:', error.response.status);
          break;
      }
    }
    return Promise.reject(error);
  }
);

axios还有哪些方法?

axios.get, axios.post, axios.options(预检), axios.patch修改

axios.all(类似promise.all)

组合模式与继承

为什么组合大于继承?

这是在功能不够确定时,组合大于继承。

例如人类在建立鸟的分类系统时,如果使用单继承,就类似文件夹分类。

TS
abstract class Bird {
    fly() {
        console.log('fly')
    }
}

鸟分为麻雀、天鹅、鹈鹕等,但有些鸟会飞,有些不会。如果鸡继承鸟的话,就会有会飞这个方法,但鸡不会飞,为了避免误用,就需要抛出异常:

TS
class chicken extends Bird {
	fly() {
		throw new Error("cannot fly")
	}
}

或者分为两个类,

TS
abstract class Bird {}

class FlyableBird {
	fly() {
		console.log('fly')
	}
}

class UnFlyableBird {}

但后来随着种类增多,可能会有生殖方式、寿命、迁徙、地域、嘴巴形状、眼睛形状等等区分,这个继承层级或者说文件夹的深度会变得越来越深。

这种情况可以选择组合模式,类似标签。

TS
interface Flyable {
	fly(): void;
}

interface EggLayable {
    layEgg(): void;
}

但这样我们就会每次都需要实现fly方法,为了减少重复代码,可以使用委托:

TS
interface Flyable {
  fly(): void;
}

interface Tweetable {
  tweet(): void;
}

interface EggLayable {
  layEgg(): void;
}

class FlyAbility implements Flyable {
  fly() {
    console.log("I can fly!");
  }
}

class TweetAbility implements Tweetable {
  tweet() {
    console.log("I can tweet!");
  }
}

class EggLayAbility implements EggLayable {
  layEgg() {
    console.log("I can lay an egg!");
  }
}

class Ostrich implements Tweetable, EggLayable {
  private tweetAbility: TweetAbility;
  private eggLayAbility: EggLayAbility;

  constructor() {
    this.tweetAbility = new TweetAbility();
    this.eggLayAbility = new EggLayAbility();
  }

  tweet() {
    this.tweetAbility.tweet();
  }

  layEgg() {
    this.eggLayAbility.layEgg();
  }
}

class Sparrow implements Flyable, Tweetable, EggLayable {
  private flyAbility: FlyAbility;
  private tweetAbility: TweetAbility;
  private eggLayAbility: EggLayAbility;

  constructor() {
    this.flyAbility = new FlyAbility();
    this.tweetAbility = new TweetAbility();
    this.eggLayAbility = new EggLayAbility();
  }

  fly() {
    this.flyAbility.fly();
  }

  layEgg() {
    this.eggLayAbility.layEgg();
  }
}

柯里化

什么是柯里化?柯里化有什么用?

real world haskell中的“Partial Function Application and Currying”章节有讲到:“In Haskell, all functions take only one argument.”

haskell
ghci> :type dropWhile
dropWhile :: (a -> Bool) -> [a] -> [a]

ghci> :type dropWhile isSpace
dropWhile isSpace :: [Char] -> [Char]

dropWhile isSpace is a function that strips leading whitespace from a string.

How is this useful? As one example, we can use it as an argument to a higher order function:

haskell
ghci> map (dropWhile isSpace) [" a","f","   e"]
["a","f","e"]

bind和curry同样是partial application,有什么不同?

bind需要绑定context,curry不需要。

TODO: 在解决这个问题之前,我们可以看一下bind的实现:

==和===有什么不同?

JS
5=='5' // '5'会被转换为number 5
0 == false // false会被转换为0
null == undefined  // true,因为它们在不进行类型转换的情况下是相等的

null === undefined // false,因为类型不同,null是object类型,undefined是undefined
console.log(typeof a);  // 输出:object
console.log(typeof b);  // 输出:undefined

Array API

JS
let L=console.log.bind(console)
let arr=[1,2,3,4]

L(arr.some(curr=> curr==2 || curr==3)) // true
L(arr.every(curr=> curr >0)) // true
L(arr.every(curr=> curr >1)) // false

let total=0
arr.forEach((v,i)=>{
    total+=v
})
L(total) // 10

L(arr.indexOf(4))
L(arr.find((curr=>curr>2))) // the first element that is bigger than 2 is 3

arr.unshift(9)
L(arr) // [9,1,2,3,4]
L(arr.toString()) // '9,1,2,3,4'
L(arr.join())

let arr1=arr.splice(1,4)
L(arr) // [9]
L(arr1) // [1,2,3,4] the element deleted

arr1.reverse()
L(arr1) // [4,3,2,1]

arr1.splice(2,0,10) 
L(arr1) // [4,3,10,2,1]

arr1.sort((a,b)=>{
    return a-b
})
L(arr1) // [1,2,3,4,10]

L(arr1.at(-1)) // 10