日常开发记录

日常开发记录

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

相关推荐
jz_ddk1 分钟前
[学习] C语言数学库函数背后的故事:`double erf(double x)`
c语言·开发语言·学习
中微子27 分钟前
React状态管理最佳实践
前端
烛阴37 分钟前
void 0 的奥秘:解锁 JavaScript 中 undefined 的正确打开方式
前端·javascript
中微子44 分钟前
JavaScript 事件与 React 合成事件完全指南:从入门到精通
前端
Hexene...1 小时前
【前端Vue】如何实现echarts图表根据父元素宽度自适应大小
前端·vue.js·echarts
初遇你时动了情1 小时前
腾讯地图 vue3 使用 封装 地图组件
javascript·vue.js·腾讯地图
dssxyz1 小时前
uniapp打包微信小程序主包过大问题_uniapp 微信小程序时主包太大和vendor.js过大
javascript·微信小程序·uni-app
爱莉希雅&&&1 小时前
技术面试题,HR面试题
开发语言·学习·面试
天天扭码1 小时前
《很全面的前端面试题》——HTML篇
前端·面试·html
xw51 小时前
我犯了错,我于是为我的uni-app项目引入环境标志
前端·uni-app