日常开发记录

日常开发记录

1.for循环的打断特定循环

看到了一段这个代码,第一次见

在 JavaScript 中,当我们需要从嵌套循环中跳出时,普通的 break 语句只能跳出当前循环。而标签语法(Labeled Statements)提供了一种更灵活的方式,允许我们从多层嵌套的循环中直接跳出。

示例1:跳出嵌套循环

javascript 复制代码
console.log("示例1输出:");
outerLoop: for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      console.log(`在i=${i}, j=${j}时跳出整个外层循环`);
      break outerLoop;
    }
    console.log(`i=${i}, j=${j}`);
  }
}

示例1输出:

i=0, j=0

i=0, j=1

i=0, j=2

i=1, j=0

在i=1, j=1时跳出整个外层循环

注意:没有i=1,j=2和任何i=2的迭代,因为整个循环被终止了。

示例2:使用continue跳到外层循环

javascript 复制代码
console.log("示例2输出:");
outerLoop: for (let i = 0; i < 3; i++) {
  console.log(`开始i=${i}的迭代`);
  for (let j = 0; j < 3; j++) {
    if (j === 1) {
      console.log(`  跳过j=${j},直接进入i的下一次迭代`);
      continue outerLoop;
    }
    console.log(`  i=${i}, j=${j}`);
  }
}

输出结果:

示例2输出:

开始i=0的迭代

i=0, j=0

跳过j=1,直接进入i的下一次迭代

开始i=1的迭代

i=1, j=0

跳过j=1,直接进入i的下一次迭代

开始i=2的迭代

i=2, j=0

跳过j=1,直接进入i的下一次迭代

注意每次j=1时,内层循环的剩余迭代(j=2)都被跳过了。

2.同步请求阻塞主线程

在看到js的XMLHttpRequest的实例方法open()时,看到了这么一句话,主线程上的同步请求很容易破坏用户体验,应该避免;实际上,许多浏览器已完全弃用主线程上的同步 XHR 支持。 想了想,同步异步不都是等待接口返回再进行赋值等的操作吗,区别在哪里呢。

首先,我需要回忆JavaScript的单线程特性。主线程负责执行代码、处理DOM、响应事件等。如果主线程被长时间的任务阻塞,页面就会卡顿,用户操作无法及时响应,导致糟糕的用户体验。而同步请求,比如同步的XMLHttpRequest,会阻塞主线程,直到请求完成,这期间所有其他操作都会被挂起。

举个例子:

javascript 复制代码
<template>
  <div class="demo">
    <h2>请求阻塞示例</h2>

    <div class="counter">
      <p>计数器: {{ counter }}</p>
      <button @click="startCounter">开始计数</button>
    </div>

    <div class="section">
      <h3>❌ 同步请求(会阻塞计数)</h3>
      <button @click="makeSyncXHR">同步请求</button>
      <p>状态: {{ syncXHRStatus }}</p>
      <p class="note">注意:点击后计数器会停止,直到请求完成</p>
    </div>

    <div class="section">
      <h3>✅ 异步请求(不会阻塞计数)</h3>
      <button @click="makeAsyncXHR">异步请求</button>
      <p>状态: {{ asyncXHRStatus }}</p>
      <p class="note">注意:点击后计数器会继续运行</p>
    </div>

    <div class="section">
      <h3>✅ Fetch 请求(不会阻塞计数)</h3>
      <button @click="makeFetchRequest">Fetch 请求</button>
      <p>状态: {{ fetchStatus }}</p>
      <p class="note">注意:点击后计数器会继续运行</p>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'Demo',
    data() {
      return {
        counter: 0,
        counterInterval: null,
        syncXHRStatus: '未开始',
        asyncXHRStatus: '未开始',
        fetchStatus: '未开始',
      }
    },
    methods: {
      startCounter() {
        if (this.counterInterval) {
          clearInterval(this.counterInterval)
        }
        this.counter = 0
        this.counterInterval = setInterval(() => {
          this.counter++
        }, 100)
      },

      // 不推荐:同步 XHR 请求
      makeSyncXHR() {
        this.syncXHRStatus = '请求中...'
        const xhr = new XMLHttpRequest()
        xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', false) // false 表示同步
        try {
          xhr.send() // 这行代码会阻塞主线程
          this.syncXHRStatus = '请求成功'
        } catch (error) {
          this.syncXHRStatus = '请求失败'
        }
      },

      // 推荐:异步 XHR 请求
      makeAsyncXHR() {
        this.asyncXHRStatus = '请求中...'
        const xhr = new XMLHttpRequest()
        xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true) // true 表示异步

        xhr.onload = () => {
          if (xhr.status === 200) {
            this.asyncXHRStatus = '请求成功'
          } else {
            this.asyncXHRStatus = '请求失败'
          }
        }

        xhr.onerror = () => {
          this.asyncXHRStatus = '请求失败'
        }

        xhr.send() // 这行代码不会阻塞主线程
      },

      // 推荐:使用 fetch API
      makeFetchRequest() {
        this.fetchStatus = '请求中...'
        fetch('https://jsonplaceholder.typicode.com/posts/1')
          .then(response => {
            if (response.ok) {
              this.fetchStatus = '请求成功'
            } else {
              this.fetchStatus = '请求失败'
            }
          })
          .catch(() => {
            this.fetchStatus = '请求失败'
          })
      },
    },
    beforeDestroy() {
      if (this.counterInterval) {
        clearInterval(this.counterInterval)
      }
    },
  }
</script>

<style scoped>
  .demo {
    padding: 20px;
  }

  .counter {
    margin-bottom: 20px;
    padding: 15px;
    background-color: #f5f5f5;
    border-radius: 4px;
  }

  .section {
    margin-bottom: 20px;
    padding: 15px;
    border: 1px solid #eee;
    border-radius: 4px;
  }

  button {
    padding: 8px 16px;
    margin-right: 10px;
    background-color: #4caf50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }

  button:hover {
    background-color: #45a049;
  }

  .note {
    color: #666;
    font-size: 0.9em;
    margin-top: 5px;
  }
</style>

效果:

可以看到用了同步的XMLHttpRequest,会阻塞主线程,定时器都要等下来,等接口返回接口后,才会继续渲染页面。

相关推荐
虾球xz1 小时前
游戏引擎学习第276天:调整身体动画
c++·学习·游戏引擎
虾球xz1 小时前
游戏引擎学习第275天:将旋转和剪切传递给渲染器
c++·学习·游戏引擎
EndingCoder1 小时前
2025年JavaScript性能优化全攻略
开发语言·javascript·性能优化
qq_386322692 小时前
华为网路设备学习-21 IGP路由专题-路由过滤(filter-policy)
前端·网络·学习
J先生x2 小时前
【IP101】图像处理进阶:从直方图均衡化到伽马变换,全面掌握图像增强技术
图像处理·人工智能·学习·算法·计算机视觉
虾球xz6 小时前
游戏引擎学习第268天:合并调试链表与分组
c++·学习·链表·游戏引擎
Y3174297 小时前
Python Day23 学习
python·学习
a濯7 小时前
element plus el-table多选框跨页多选保留
javascript·vue.js
song_ly0017 小时前
深入理解软件测试覆盖率:从概念到实践
笔记·学习·测试
蓝婷儿7 小时前
前端面试每日三题 - Day 32
前端·面试·职场和发展