23-april19th


vscode调试与log

1.准备工作

点击调试

选择运行环境 (chrome 或者是 node)

注意:配置json文件时,端口号要和项目端口号一致,

否则无法运行调试

2.开始调试

断点调试:

点击代码左侧的列就可以出现红色的断点,执行时会在这里停住,

同时也可以在左侧看到调用栈和函数名,非常适合用来调试源码。

添加记录点:

记录点的作用相当于console.log, 变量需要用 {} 包裹,

代码运行就会打印出对应的值,同时在代码里也不用写很多console,省去了后面还要再次删掉的麻烦。

React–Query使用(v5)

当依赖项为undefined、null、’’ 时(视为无效参数),不发起请求

function Todos() {
  const [filter, setFilter] = React.useState('')

  const { data } = useQuery({
      queryKey: ['todos', filter],
      queryFn: () => fetchTodos(filter),
      // ⬇️ disabled as long as the filter is empty : 只要筛选器为空,就会被禁用
       // 只有 filter 变化、且不为空时,发起请求
      // 避免值为空时发起的无意义请求(值为空请求就会失败,react-query会不断进行请求,造成浪费)
      enabled: !!filter
  })
  ...
  ..
  .
}

React 有状态函数组件 依然是纯函数

见Meat(FaceBook工程师 黄玄 回答)

https://www.zhihu.com/question/537538929

??

value1 ?? value2
?? 在value1和value2之间,只有当value1为null或者 undefined 时取value2,否则取value1(0,false,""被认为是有意义的,所以还

是取value1)

typescript 类型断言

as

let student = {}
// let student: {}

student.name = 'jack'
// 类型“{}”上不存在属性“name”。

student.age = 18
// 类型“{}”上不存在属性“age”。
// 接口
interface Person{
  name:string;
  age: number
}

let student = {} as Person
// let student: Person

student.name = 'jack' // 不会再报错
student.age = 18

<>

function getLength(something: string | number): number {
    return (<string>something).length;
}

let a: any
let b = <string>a // string
注意: <>断言在react组件中与jsx语法冲突!,一般不可用。

!(非空断言)

let num:number | null | undefined
// let num: number | null | undefined 

// let num2 = num.toFixed(2)
// num可能为 “null” 或“未定义”

let num2 = num!.toFixed(2) // string

双重断言

<span>{console.log("render") as unknown as string}</span>

超时报错、未超时正常返回数据

模拟请求数据的方法

/**
 * 假设该数据请求函数 n s 后才能返回数据
 * @returns Promise<any>
 */
function queryfn() {
  return new Promise(function (reslove) {
    setTimeout(function () {
      console.log("1111");
      reslove(true);
    }, 5000);
  });
}

type one

/**
 *
 * @param {Promise<any>} queryfn 请求数据的函数
 * @param {number} delaty 超时的时限,超时报错
 */
function isTimeOut(queryfn, delaty = 4000) {
  new Promise(function (reslove, reject) {
    setTimeout(function () {
      reject(new Error("request timeout!"));
    }, delaty);

    console.log("111");
    queryfn().then((res) => {
      console.log("res----->", res);
      reslove(res);
    });
  });
}

// console.log("isTimeOut", isTimeOut(queryfn, 6000));

type two

/**
 * 
 * @param {Promise<any>} p1 
 * @param {number} timeout 
 * @returns 
 */
const timeoutReject = (p1, timeout = 3000) => {
  const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("网络超时");
    }, timeout);
  });
  return Promise.race([p1, p2]);
};

timeoutReject(queryfn())
  .then((res) => {
    console.log("result", res);
  })
  .catch((err) => {
    console.log("error", err);
  });

若请求前的先决条件不满足,多次调用直到满足

// 先决条件

function isOK() {
  return false;
}

function getData() {
  return "data";
}

/**
 * 
 * @param {() => boolean} queryfn 会返回 true 或 false
 * @param {() => Promise<any>} callback 请求数据的方法
 * time: 重新调用的时间间隔、以1.5倍递增,若去除则每次调用时间一样
 */

function simplePoller(queryfn, callback) {
  let time = 1000;

  const poll = () => {
    console.log("time", time);
    if (queryfn()) {
      callback();
      return;
    }
    setTimeout(poll, time);
    time *= 1.5
  };
  setTimeout(poll, time);
}

console.log("deepQuery", simplePoller(isOK, getData));

请求出错,重试次数

  function likeData() {
    return new Promise(function (reslove, reject) {
      // reject("请求出错");
      setTimeout(() => {
        reslove("jieguo");
      }, 5000);
    });
  }

type one

  // 请求失败重试指定的次数
  function retryFunc(likeData, trymax) {
    let num = 0;

    function autopoll(reslove) {
      num++;
      if (num > trymax) {
        return;
      }
      likeData()
        .then((res) => {
          console.log("res", res);
          reslove(res);
        })
        .catch((err) => {
          console.log("eerrr", err);
          setTimeout(autopoll, 5000);
        });
    }

    return new Promise(function (reslove, reject) {
      // setTimeout(function () { //  混合超时报错(可选)
      //   reject("timeout");
      // }, 5000);
      autopoll(reslove);
    });
  }

  // console.log("retryFunc", retryFunc(likeData, 6));

type two

  // 另一个版本

  function retryTwo(likeData, max) {
    let num = 0;

    function poll() {
      return likeData()
        .then((res) => {
          // if (res.code !== 200) {
          //   throw new Error("requst failed!");
          // }
          // return res.data;
          return res;
        })
        .catch((err) => {
          num++;
          console.log("eeeeeeee", err);
          if (num < max) {
            setTimeout(function () {
              poll();
            }, 2000);
          } else {
            throw new Error(`已经连续请求${num}次`);
          }
        });
    }

    return poll();
  }

jsx不能console?

<span>{console.log("render")}</span>
不能将类型“void”分配给类型“ReactNode”。ts(2322)
index.d.ts(1376, 9): 所需类型来自属性 "children",在此处的 "DetailedHTMLProps, HTMLSpanElement>" 类型上声明该属性

解决

<span>{console.log("render") as unknown as string}</span>

使用回调函数接收异步数据

// 模拟数据
function getData() {
  return new Promise(function(reslove, reject){
    reslove(
      [
        {
          name: '巨diao',
          age: 28
        },
        {
          name: '牛恒',
          age: 25
        },
      ]
    )
  })
}

async function test(callback){
  const res = await getData();
  console.log('res', res);
  callback(res)
}

// 回调函数
function demo(value) {
  console.log('value', value);
}

test(demo)

文章作者: KarlFranz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 reprint policy. If reproduced, please indicate source KarlFranz !
评论
  目录