在这里插入图片描述
@[toc]( 前端打工人必学-3分钟搞定async await Sleep等待效果(附避坑指南))

前端打工人必学-3分钟搞定async await Sleep等待效果(附避坑指南)

开场白:这玩意儿真能让我少加班?

说实话,我刚开始写前端那会儿,最怕的就是处理"等一等"这个需求。你说让程序睡一会儿?JavaScript直接给你个白眼——老子是单线程的,你让我睡,整个页面都给你卡死信不信?

但需求不会因为你不会就消失。老板说要轮询接口,产品经理说要动画延迟,测试妹子说按钮连点会崩… 我试过用setTimeout嵌套地狱,试过用setInterval手动计数,代码写得像意大利面条,自己看了都想吐。

直到某天深夜,我在Stack Overflow上看到一个答案,突然开窍了。原来async/await配合Promise能玩出这种花样?代码瞬间从"城中村自建房"升级成"精装公寓"。今天就把这套组合拳毫无保留地分享出来,保证你看完就能上手,下次遇到等待需求不再抓瞎。


先说个扎心真相:JavaScript压根没有真正的sleep函数

很多新手(包括当年的我)第一次搜"JS sleep"的时候,估计都看到过这种"野生教程":

// 千万别这么写!这是错误的示范!
function badSleep(seconds) {
  const start = Date.now();
  while (Date.now() - start < seconds * 1000) {
    // 空循环,卡住主线程
  }
}

兄弟,你要是敢在项目中写这玩意儿,浏览器直接表演一个页面无响应。用户疯狂点关闭按钮,CPU风扇转得像直升机,测试妹子提着刀就过来了。

JavaScript的设计哲学就是非阻塞,它从来没有C语言那种sleep(3)的函数。这不是缺陷,是特性。但问题是我们确实需要"等一等"的场景啊,怎么办?

答案就是假装睡觉——让出主线程,定个闹钟,时间到了再回来继续。听起来简单,但实现方式决定了你是"优雅地等"还是"粗暴地卡"。


为啥前端也需要假装睡一会儿

可能有人觉得,sleep不是后端的事吗?前端不就是点点按钮、发发请求?太天真了。我随便举几个血淋淋的真实场景:

场景一:接口轮询的尊严

// 错误示范:疯狂请求,服务器直接拉黑你
while (true) {
  const data = await fetch('/api/status');
  if (data.ready) break;
  // 没有sleep,CPU爆炸,服务器也爆炸
}

场景二:动画的节奏感
用户点击提交后,按钮要先转个圈,再显示成功,最后跳转。没有延迟控制,动画像抽风一样快,用户体验稀烂。

场景三:防抖节流的优雅实现
搜索框输入停止后,等个300毫秒再发请求。这300毫秒怎么等?用sleep封装比手写定时器清爽一百倍。

场景四:顺序执行的异步流程
先上传图片,等上传完再更新用户信息,最后刷新列表。不用await的话,回调嵌套三层起步,维护起来想死。

场景五:给用户一点"正在处理"的错觉
有些操作其实很快,但用户觉得快=不靠谱。故意等个500毫秒再出结果,用户反而觉得"这系统真专业"。(别笑,心理学就是这么神奇)


async和await到底是个啥关系

这俩货是绑定CP,单飞必死。我见过太多新手只写async不写await,或者反过来,然后对着报错信息怀疑人生。

async是干嘛的?
它就是给函数贴个标签,告诉JS引擎:“嘿,我这个函数里可能有异步操作,你帮我包成Promise返回。”

// 普通函数
function normal() {
  return "hello";
}

// async函数
async function asyncFunc() {
  return "hello"; // 实际返回 Promise.resolve("hello")
}

console.log(normal()); // "hello"
console.log(asyncFunc()); // Promise {<fulfilled>: "hello"}

看到没?哪怕你return的是普通值,async也会自动包成Promise。这就是它的本职工作。

await是干嘛的?
它是暂停键,但注意是协程级别的暂停,不是线程级别的阻塞。简单说就是:“我先去旁边歇会儿,后面的代码等我通知再执行,但主线程你们继续用,别等我。”

async function demo() {
  console.log("开始");
  await sleep(1000); // 这里暂停,但页面不会卡
  console.log("1秒后");
}

demo();
console.log("我不用等demo");
// 输出顺序:开始 -> 我不用等demo -> 1秒后

关键点来了:await只能用在async函数内部。你如果在普通函数里写await,引擎直接报错:SyntaxError: await is only valid in async functions


核心代码就这几行但坑不少

好了,铺垫了这么多,上正餐。实现sleep的核心代码确实简单到离谱:

/**
 * 睡眠函数 - 让程序优雅地等待指定时间
 * @param {number} ms - 等待时间,单位毫秒
 * @returns {Promise} - 时间到了自动resolve的Promise
 */
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

就三行,没了。但别急着复制粘贴,这里面的门道多了去了。

第一坑:时间单位搞错
我见过有人这样写:

await sleep(3); // 以为是3秒,实际是3毫秒,眨眼就没了

记住,JS的世界里默认都是毫秒。要睡3秒得写sleep(3000)。如果你嫌算零麻烦,可以封装个更友好的版本:

// 更人性化的版本,支持秒和毫秒
function sleep(time, unit = 'ms') {
  const ms = unit === 's' ? time * 1000 : time;
  return new Promise(resolve => setTimeout(resolve, ms));
}

// 用法
await sleep(3, 's'); // 睡3秒
await sleep(500);    // 睡500毫秒

第二坑:忘记处理reject
上面的sleep函数永远会resolve,不会reject。但有时候我们需要可取消的sleep,比如用户突然切换页面了,还在等的定时器就成了内存泄漏。

/**
 * 可取消的sleep - 进阶版
 * @param {number} ms - 等待时间
 * @param {AbortSignal} signal - 用于取消的信号
 */
function cancellableSleep(ms, signal) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(resolve, ms);
    
    // 如果外部传了signal,监听取消事件
    if (signal) {
      signal.addEventListener('abort', () => {
        clearTimeout(timer);
        reject(new Error('Sleep cancelled'));
      });
    }
  });
}

// 使用示例
const controller = new AbortController();

try {
  await cancellableSleep(5000, controller.signal);
  console.log('睡醒了');
} catch (err) {
  console.log('被叫醒了:', err.message);
}

// 3秒后取消
setTimeout(() => controller.abort(), 3000);

第三坑:循环里的await
这是性能杀手,新手最容易踩:

// 错误示范:串行执行,慢如蜗牛
async function processItems(items) {
  for (const item of items) {
    await sleep(100); // 每个等100ms,100个就是10秒
    await process(item);
  }
}

如果items有100个,这段代码要跑10秒+。但很多时候这些操作其实可以并行:

// 正确示范:并行执行,只要100ms
async function processItems(items) {
  await Promise.all(
    items.map(async (item) => {
      await sleep(100);
      return process(item);
    })
  );
}

第四坑:错误处理姿势不对
await最大的好处就是可以用try-catch,但很多人写错了:

// 错误示范:catch不到reject
async function badErrorHandle() {
  try {
    await Promise.reject('出错了');
  } catch (e) {
    console.log('捕获到:', e);
  }
}

// 正确示范:await后面跟的Promise reject了,会被catch捕获
async function goodErrorHandle() {
  try {
    const result = await fetch('/api/data');
    if (!result.ok) throw new Error('HTTP错误');
    return await result.json();
  } catch (e) {
    console.error('请求失败:', e);
    // 可以在这里重试或降级
  }
}

这方案到底香在哪里

香点一:代码可读性起飞
对比下回调地狱和async/await的版本:

// 回调地狱版(别这么写,会瞎)
function oldStyle() {
  setTimeout(() => {
    console.log('第一步');
    setTimeout(() => {
      console.log('第二步');
      setTimeout(() => {
        console.log('第三步');
      }, 1000);
    }, 1000);
  }, 1000);
}

// async/await版(清爽)
async function newStyle() {
  await sleep(1000);
  console.log('第一步');
  await sleep(1000);
  console.log('第二步');
  await sleep(1000);
  console.log('第三步');
}

香点二:错误处理统一
以前用then/catch链式调用,错误处理分散在各处。现在一个try-catch包全场:

async function robustFetch() {
  try {
    const user = await fetchUser();
    const orders = await fetchOrders(user.id);
    const details = await fetchDetails(orders[0].id);
    return details;
  } catch (e) {
    // 不管哪一步出错,都在这里处理
    console.error('流程中断:', e);
    return null;
  }
}

香点三:调试友好
在async函数里打断点,代码是顺序执行的,调试器一步步走很直观。回调地狱里断点跳来跳去,脑子都乱了。

香点四:类型支持好
如果你用TypeScript,async函数的返回类型自动是Promise<T>,类型推断很准确:

async function typedSleep(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// 使用时类型安全
const result: void = await typedSleep(1000);

但也不是没有槽点

槽点一:性能陷阱
前面提到的循环await只是冰山一角。更隐蔽的是不必要的async包装

// 没必要,普通函数就行
async function add(a, b) {
  return a + b; // 同步操作包成Promise,浪费
}

// 应该这样
function add(a, b) {
  return a + b;
}

每个async函数调用都有Promise创建的开销,虽然现代引擎优化得很好,但高频调用还是要注意。

槽点二:调试时的"异步堆栈"
错误堆栈里可能看不到完整的调用链,因为await把调用拆成了多个事件循环周期。Chrome DevTools现在支持"Async Stack Traces"了,但老浏览器还是头疼。

槽点三:并发控制麻烦
Promise.all虽然能并行,但如果有100个请求同时发,服务器直接503。需要手动控制并发数:

/**
 * 控制并发数的map
 * @param {Array} items - 要处理的数组
 * @param {Function} fn - 异步处理函数
 * @param {number} concurrency - 最大并发数
 */
async function asyncPool(items, fn, concurrency = 5) {
  const ret = [];
  const executing = [];
  
  for (const item of items) {
    const p = Promise.resolve().then(() => fn(item));
    ret.push(p);
    
    if (items.length >= concurrency) {
      const e = p.then(() => executing.splice(executing.indexOf(e), 1));
      executing.push(e);
      if (executing.length >= concurrency) {
        await Promise.race(executing);
      }
    }
  }
  
  return Promise.all(ret);
}

// 使用:最多同时发5个请求
await asyncPool(urls, fetchUrl, 5);

实际项目里我是这么玩的

玩法一:接口重试机制
接口不稳定?自动重试3次,每次等的时间翻倍(指数退避):

/**
 * 带重试的fetch
 * @param {string} url - 请求地址
 * @param {object} options - fetch选项
 * @param {number} maxRetries - 最大重试次数
 */
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
  for (let i = 0; i <= maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      if (response.ok) return response;
      throw new Error(`HTTP ${response.status}`);
    } catch (error) {
      if (i === maxRetries) throw error;
      
      // 指数退避:第一次等1秒,第二次等2秒,第三次等4秒
      const delay = Math.pow(2, i) * 1000;
      console.log(`${i + 1}次失败,${delay}ms后重试...`);
      await sleep(delay);
    }
  }
}

// 使用
try {
  const data = await fetchWithRetry('/api/unstable-endpoint');
} catch (e) {
  console.error('彻底失败:', e);
}

玩法二:防止重复提交
表单提交后禁用按钮,等3秒再恢复,防止手贱用户疯狂点击:

class FormSubmitter {
  constructor() {
    this.isSubmitting = false;
  }

  async submit(formData) {
    if (this.isSubmitting) {
      alert('别急,正在处理...');
      return;
    }

    this.isSubmitting = true;
    const btn = document.querySelector('#submitBtn');
    const originalText = btn.textContent;
    
    try {
      btn.disabled = true;
      btn.textContent = '提交中...';
      
      const result = await fetch('/api/submit', {
        method: 'POST',
        body: formData
      });
      
      if (!result.ok) throw new Error('提交失败');
      
      // 成功后给个视觉反馈,等一会儿再跳转
      btn.textContent = '提交成功!';
      btn.classList.add('success');
      await sleep(1500); // 让用户看到成功状态
      
      window.location.href = '/success';
      
    } catch (error) {
      btn.textContent = '提交失败,请重试';
      btn.classList.add('error');
      await sleep(2000); // 错误状态也显示一会儿
      btn.textContent = originalText;
      btn.classList.remove('error');
    } finally {
      this.isSubmitting = false;
      btn.disabled = false;
      btn.classList.remove('success');
    }
  }
}

玩法三:轮询直到条件满足
检查文件处理状态,每2秒查一次,最多查30次(1分钟):

/**
 * 轮询检查状态
 * @param {string} taskId - 任务ID
 * @param {number} interval - 轮询间隔(ms)
 * @param {number} maxAttempts - 最大尝试次数
 */
async function pollStatus(taskId, interval = 2000, maxAttempts = 30) {
  for (let i = 0; i < maxAttempts; i++) {
    const response = await fetch(`/api/tasks/${taskId}`);
    const { status, result } = await response.json();
    
    if (status === 'completed') {
      return result;
    }
    
    if (status === 'failed') {
      throw new Error('任务执行失败');
    }
    
    // 还在处理中,等一会儿再查
    console.log(`${i + 1}次检查,状态:${status}...`);
    await sleep(interval);
  }
  
  throw new Error('轮询超时');
}

// 使用
try {
  const result = await pollStatus('task-123');
  console.log('任务完成:', result);
} catch (e) {
  console.error('轮询出错:', e);
}

玩法四:顺序动画队列
多个动画按顺序执行,中间有延迟:

class AnimationQueue {
  constructor() {
    this.queue = [];
    this.running = false;
  }

  add(animationFn, delay = 0) {
    this.queue.push({ fn: animationFn, delay });
    if (!this.running) this.run();
    return this; // 链式调用
  }

  async run() {
    this.running = true;
    
    while (this.queue.length > 0) {
      const { fn, delay } = this.queue.shift();
      
      if (delay > 0) {
        await sleep(delay);
      }
      
      await fn(); // 等待动画完成
    }
    
    this.running = false;
  }
}

// 使用:优雅的链式动画
const anim = new AnimationQueue();

anim
  .add(() => moveBox('left'), 500)   // 等500ms,然后左移
  .add(() => rotateBox(), 300)       // 等300ms,然后旋转  
  .add(() => fadeOutBox(), 200)      // 等200ms,然后淡出
  .add(() => console.log('动画完成')); // 最后回调

玩法五:批量请求限速
有1000条数据要上传,但不能一次性全发,得一批一批来:

/**
 * 批量处理,控制并发和间隔
 * @param {Array} items - 数据项
 * @param {Function} processor - 处理函数
 * @param {object} options - 配置
 */
async function batchProcess(items, processor, options = {}) {
  const {
    batchSize = 10,      // 每批处理数量
    interval = 1000,     // 批次间隔
    onProgress           // 进度回调
  } = options;

  const results = [];
  
  for (let i = 0; i < items.length; i += batchSize) {
    const batch = items.slice(i, i + batchSize);
    
    // 处理当前批次(并行)
    const batchResults = await Promise.all(
      batch.map(item => processor(item))
    );
    
    results.push(...batchResults);
    
    // 报告进度
    if (onProgress) {
      onProgress({
        completed: Math.min(i + batchSize, items.length),
        total: items.length,
        percentage: Math.round((i + batchSize) / items.length * 100)
      });
    }
    
    // 不是最后一批的话,等一会儿
    if (i + batchSize < items.length) {
      await sleep(interval);
    }
  }
  
  return results;
}

// 使用示例
const data = Array.from({length: 100}, (_, i) => ({ id: i }));

await batchProcess(
  data,
  async (item) => {
    await uploadToServer(item);
    return { id: item.id, status: 'success' };
  },
  {
    batchSize: 5,
    interval: 2000,
    onProgress: ({ completed, total, percentage }) => {
      console.log(`进度: ${completed}/${total} (${percentage}%)`);
    }
  }
);

代码跑不起来先查这几个地方

第一查:await是不是写在async外面了
这是新手最高频的错误:

// 错误!顶级await在老浏览器不支持
const data = await fetch('/api/data');

// 正确:包在async函数里
async function init() {
  const data = await fetch('/api/data');
}

如果你用的是ES模块(<script type="module">),现代浏览器支持顶级await,但Node.js老版本不支持。

第二查:Promise有没有resolve
sleep函数没resolve,await就永远等下去:

// 错误的sleep,永远卡住
function badSleep(ms) {
  return new Promise(() => {
    setTimeout(() => {
      console.log('时间到了');
      // 忘了调用resolve!
    }, ms);
  });
}

// 正确的
function goodSleep(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}

第三查:定时器时间单位
前面说过,再强调一遍:setTimeoutsleep都是毫秒。睡5秒写sleep(5000),不是sleep(5)

第四查:未捕获的Promise rejection
如果await的Promise reject了,但没有try-catch,控制台会报"Uncaught (in promise)",程序可能中断:

// 危险:可能抛出未捕获的错误
async function risky() {
  await Promise.reject('boom'); // 这里会抛出
}

// 安全:包上try-catch
async function safe() {
  try {
    await Promise.reject('boom');
  } catch (e) {
    console.error('捕获:', e);
  }
}

第五查:this指向问题
在类方法里用await,注意this别丢了:

class MyClass {
  constructor() {
    this.value = 42;
  }

  // 错误:箭头函数没问题,但普通函数要注意
  async fetchData() {
    setTimeout(function() {
      console.log(this.value); // undefined!this丢了
    }, 100);
  }

  // 正确:用箭头函数保留this
  async fetchDataFixed() {
    setTimeout(() => {
      console.log(this.value); // 42
    }, 100);
  }
}

几个让代码更骚的操作技巧

技巧一:带超时的sleep
有时候等太久不如直接报错:

/**
 * 带超时的sleep
 * @param {number} ms - 等待时间
 * @param {string} message - 超时提示
 */
function sleepWithTimeout(ms, message = '操作超时') {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(resolve, ms);
    
    // 可以结合AbortController实现外部取消
    // 这里简单演示超时逻辑
  });
}

// 配合Promise.race实现超时控制
async function fetchWithTimeout(url, timeout = 5000) {
  const timeoutPromise = new Promise((_, reject) => {
    setTimeout(() => reject(new Error('请求超时')), timeout);
  });
  
  return Promise.race([
    fetch(url),
    timeoutPromise
  ]);
}

技巧二:进度条sleep
等待的时候给用户反馈,别让用户干等:

/**
 * 带进度回调的sleep
 * @param {number} ms - 总等待时间
 * @param {Function} onProgress - 进度回调(0-100)
 * @param {number} steps - 更新次数
 */
async function sleepWithProgress(ms, onProgress, steps = 10) {
  const stepTime = ms / steps;
  
  for (let i = 0; i <= steps; i++) {
    onProgress(Math.round((i / steps) * 100));
    if (i < steps) await sleep(stepTime);
  }
}

// 使用:模拟加载进度
const progressBar = document.querySelector('.progress-bar');

await sleepWithProgress(
  3000, 
  (percent) => {
    progressBar.style.width = `${percent}%`;
    progressBar.textContent = `${percent}%`;
  },
  20 // 更新20次,每150ms一次
);

技巧三:条件sleep
满足某个条件才继续,否则一直等(带超时):

/**
 * 等待条件满足
 * @param {Function} condition - 返回boolean的条件函数
 * @param {number} checkInterval - 检查间隔
 * @param {number} timeout - 最大等待时间
 */
async function waitFor(condition, checkInterval = 100, timeout = 10000) {
  const startTime = Date.now();
  
  while (!condition()) {
    if (Date.now() - startTime > timeout) {
      throw new Error('等待条件超时');
    }
    await sleep(checkInterval);
  }
}

// 使用:等待某个元素出现
await waitFor(
  () => document.querySelector('#dynamic-content') !== null,
  200,    // 每200ms检查一次
  5000    // 最多等5秒
);

技巧四:随机sleep
模拟真实场景,避免请求太规律被识别为爬虫:

/**
 * 随机时间sleep
 * @param {number} min - 最小时间(ms)
 * @param {number} max - 最大时间(ms)
 */
function randomSleep(min, max) {
  const ms = Math.floor(Math.random() * (max - min + 1)) + min;
  return sleep(ms);
}

// 使用:请求间隔1-3秒随机
for (const url of urls) {
  await fetch(url);
  await randomSleep(1000, 3000);
}

性能优化这块得注意

优化点一:避免串行await
能并行的别串行:

// 慢:串行执行,总时间 = a + b + c
const a = await fetchA();
const b = await fetchB();
const c = await fetchC();

// 快:并行执行,总时间 = max(a, b, c)
const [a, b, c] = await Promise.all([
  fetchA(),
  fetchB(),
  fetchC()
]);

优化点二:控制并发数
前面提到的asyncPool自己实现麻烦?可以用p-limit库:

import pLimit from 'p-limit';

const limit = pLimit(5); // 最多5个并发

const results = await Promise.all(
  urls.map(url => limit(() => fetch(url)))
);

优化点三:及时清理定时器
如果sleep被取消了,记得清理setTimeout,避免内存泄漏:

function cleanableSleep(ms) {
  let timer;
  
  const promise = new Promise(resolve => {
    timer = setTimeout(resolve, ms);
  });
  
  promise.cancel = () => {
    clearTimeout(timer);
  };
  
  return promise;
}

// 使用
const sleepPromise = cleanableSleep(5000);

// 3秒后取消
setTimeout(() => sleepPromise.cancel(), 3000);

try {
  await sleepPromise;
} catch (e) {
  // 处理取消
}

优化点四:大任务别堵主线程
如果sleep期间还要做大量计算,考虑用Web Worker:

// worker.js
self.onmessage = async function(e) {
  const { duration } = e.data;
  await sleep(duration);
  self.postMessage('done');
};

// 主线程
const worker = new Worker('worker.js');
worker.postMessage({ duration: 5000 });
worker.onmessage = () => console.log('后台任务完成');

最后说点掏心窝子的

说实话,async/await+sleep这套组合拳,是我从前端小白进阶到能独立负责项目的关键转折点之一。以前看到异步操作就头疼,现在反而觉得同步代码写起来更别扭。

但记住几个原则:

不要为了用而用。如果一个操作本身就是同步的,别强行包成async。代码是写给人看的,过度设计比不设计还可怕。

错误处理要到位await让异步代码看起来像同步的,但错误处理不能省略。每个await后面都可能抛出错误,想清楚怎么兜底。

性能意识要有。循环里无脑await、大量并行请求不控制并发,这些坑踩一次就知道疼了。开发环境数据量少没问题,生产环境分分钟教做人。

兼容性要考虑。虽然现在async/await支持度很好了,但老项目可能要转译。如果你在用Babel,确保配置了@babel/plugin-transform-runtime

面试的时候,面试官特别喜欢问异步相关的问题。从"回调地狱"到"Promise",再到"async/await",能讲清楚演进过程,说明你真的有实战经验,不只是背API。

好了,这篇从原理到实战、从坑点到优化,应该覆盖了你工作中90%的sleep场景。代码片段可以直接复制到项目里用,但建议先理解原理,再根据业务调整。

有啥问题或者更好的玩法,欢迎交流。前端这条路,就是不断踩坑、填坑、再踩新坑的过程。共勉!

欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

推荐:DTcode7的博客首页。
一个做过前端开发的产品经理,经历过睿智产品的折磨导致脱发之后,励志要翻身农奴把歌唱,一边打入敌人内部一边持续提升自己,为我们广大开发同胞谋福祉,坚决抵制睿智产品折磨我们码农兄弟!


专栏系列(点击解锁) 学习路线(点击解锁) 知识定位
《微信小程序相关博客》 持续更新中~ 结合微信官方原生框架、uniapp等小程序框架,记录请求、封装、tabbar、UI组件的学习记录和使用技巧等
《AIGC相关博客》 持续更新中~ AIGC、AI生产力工具的介绍,例如stable diffusion这种的AI绘画工具安装、使用、技巧等总结
《HTML网站开发相关》 《前端基础入门三大核心之html相关博客》 前端基础入门三大核心之html板块的内容,入坑前端或者辅助学习的必看知识
《前端基础入门三大核心之JS相关博客》 前端JS是JavaScript语言在网页开发中的应用,负责实现交互效果和动态内容。它与HTML和CSS并称前端三剑客,共同构建用户界面。
通过操作DOM元素、响应事件、发起网络请求等,JS使页面能够响应用户行为,实现数据动态展示和页面流畅跳转,是现代Web开发的核心
《前端基础入门三大核心之CSS相关博客》 介绍前端开发中遇到的CSS疑问和各种奇妙的CSS语法,同时收集精美的CSS效果代码,用来丰富你的web网页
《canvas绘图相关博客》 Canvas是HTML5中用于绘制图形的元素,通过JavaScript及其提供的绘图API,开发者可以在网页上绘制出各种复杂的图形、动画和图像效果。Canvas提供了高度的灵活性和控制力,使得前端绘图技术更加丰富和多样化
《Vue实战相关博客》 持续更新中~ 详细总结了常用UI库elementUI的使用技巧以及Vue的学习之旅
《python相关博客》 持续更新中~ Python,简洁易学的编程语言,强大到足以应对各种应用场景,是编程新手的理想选择,也是专业人士的得力工具
《sql数据库相关博客》 持续更新中~ SQL数据库:高效管理数据的利器,学会SQL,轻松驾驭结构化数据,解锁数据分析与挖掘的无限可能
《算法系列相关博客》 持续更新中~ 算法与数据结构学习总结,通过JS来编写处理复杂有趣的算法问题,提升你的技术思维
《IT信息技术相关博客》 持续更新中~ 作为信息化人员所需要掌握的底层技术,涉及软件开发、网络建设、系统维护等领域的知识
《信息化人员基础技能知识相关博客》 无论你是开发、产品、实施、经理,只要是从事信息化相关行业的人员,都应该掌握这些信息化的基础知识,可以不精通但是一定要了解,避免日常工作中贻笑大方
《信息化技能面试宝典相关博客》 涉及信息化相关工作基础知识和面试技巧,提升自我能力与面试通过率,扩展知识面
《前端开发习惯与小技巧相关博客》 持续更新中~ 罗列常用的开发工具使用技巧,如 Vscode快捷键操作、Git、CMD、游览器控制台等
《photoshop相关博客》 持续更新中~ 基础的PS学习记录,含括PPI与DPI、物理像素dp、逻辑像素dip、矢量图和位图以及帧动画等的学习总结
日常开发&办公&生产【实用工具】分享相关博客》 持续更新中~ 分享介绍各种开发中、工作中、个人生产以及学习上的工具,丰富阅历,给大家提供处理事情的更多角度,学习了解更多的便利工具,如Fiddler抓包、办公快捷键、虚拟机VMware等工具

吾辈才疏学浅,摹写之作,恐有瑕疵。望诸君海涵赐教。望轻喷,嘤嘤嘤

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。愿斯文对汝有所裨益,纵其简陋未及渊博,亦足以略尽绵薄之力。倘若尚存阙漏,敬请不吝斧正,俾便精进!

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐