日常开发记录

日常开发记录

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

相关推荐
a东方青2 分钟前
vue3学习笔记之属性绑定
vue.js·笔记·学习
东部欧安时9 分钟前
研一自救指南 - 07. CSS面向面试学习
前端·css
沉默是金~20 分钟前
Vue+Notification 自定义消息通知组件 支持数据分页 实时更新
javascript·vue.js·elementui
涵信21 分钟前
第十二节:原理深挖-React Fiber架构核心思想
前端·react.js·架构
在下千玦25 分钟前
#去除知乎中“盐选”付费故事
javascript
ohMyGod_12326 分钟前
React-useRef
前端·javascript·react.js
每一天,每一步28 分钟前
AI语音助手 React 组件使用js-audio-recorder实现,将获取到的语音转成base64发送给后端,后端接口返回文本内容
前端·javascript·react.js
上趣工作室28 分钟前
vue3专题1------父组件中更改子组件的属性
前端·javascript·vue.js
冯诺一没有曼32 分钟前
无线网络入侵检测系统实战 | 基于React+Python的可视化安全平台开发详解
前端·安全·react.js
豆芽81932 分钟前
科学研究:怎么做
学习·科研·学习方法