日常开发记录

日常开发记录

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

相关推荐
布兰妮甜10 分钟前
单例模式在前端(JavaScript)中的实现与应用
前端·javascript·单例模式
Mintopia10 分钟前
Three.js 加载模型文件:从二进制到像素的奇幻漂流
前端·javascript·three.js
StrongerIrene20 分钟前
rs build 的process.env的值undefined解决方案
开发语言·javascript·ecmascript
前端小巷子29 分钟前
跨域问题解决方案:JSONP
前端·javascript·面试
eric*168837 分钟前
尚硅谷张天禹老师课程配套笔记
前端·vue.js·笔记·vue·尚硅谷·张天禹·尚硅谷张天禹
程序员爱钓鱼1 小时前
Go语言中的反射机制 — 元编程技巧与注意事项
前端·后端·go
GIS之路1 小时前
GeoTools 结合 OpenLayers 实现属性查询(二)
前端·信息可视化
just小千1 小时前
重学React(二):添加交互
javascript·react.js·交互
烛阴1 小时前
一文搞懂 Python 闭包:让你的代码瞬间“高级”起来!
前端·python
AA-代码批发V哥1 小时前
HTML之表单结构全解析
前端·html