日常开发记录

日常开发记录

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,会阻塞主线程,定时器都要等下来,等接口返回接口后,才会继续渲染页面。

相关推荐
GIS之路2 分钟前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug6 分钟前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu121387 分钟前
React面向组件编程
开发语言·前端·javascript
学历真的很重要8 分钟前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
持续升级打怪中29 分钟前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路33 分钟前
GDAL 实现矢量合并
前端
hxjhnct35 分钟前
React useContext的缺陷
前端·react.js·前端框架
冰暮流星42 分钟前
javascript逻辑运算符
开发语言·javascript·ecmascript
前端 贾公子1 小时前
从入门到实践:前端 Monorepo 工程化实战(4)
前端
菩提小狗1 小时前
Sqlmap双击运行脚本,双击直接打开。
前端·笔记·安全·web安全