js 程序执行与顺序实现详解

JS程序执行与顺序实现详解

JS是一门单线程语言,指在一个时间只执行一个任务。虽然JS是单线程语言,但是它可以利用事件循环和回调实现异步编程。

1. JS代码的执行顺序

JS代码是从上往下一行一行执行的,但是在执行JS代码时,遇到如下情况就会把当前任务挂起,去执行其他任务:

  1. 等待Web API返回结果,例如:发起Ajax请求等。
  2. 等待定时器。
  3. 等待事件发生。

1.1 Web API的异步处理

当执行代码中遇到Web API时,JS并不会一直等待Web API的完成,而是先将代码执行完毕,然后将Web API相关的回调函数加入异步队列中排队等待Web API返回结果,待结果返回后,JS引擎从异步队列中读取相应回调函数。

示例:

console.log('start');
setTimeout(function() {
  console.log('callback');
}, 1000);
console.log('end');

该示例中,先输出“start”,实际上是同步任务。接着执行定时器,将回调函数异步添加到任务队列中,然后输出“end”。但是需要等待1秒后,从异步队列中读取回调函数,输出“callback”。

1.2 Promise的异步处理

Promise是JS提供的异步编程的解决方案,ES6中的新特性。Promise可以将异步代码封装成Promise对象,实现更为优雅的异步代码的书写。

示例:

console.log('start');
new Promise((resolve, reject) => {
  console.log('promise start');
  setTimeout(() => {
    resolve('promise callback');
  }, 1000);
}).then((res) => {
  console.log('promise then:', res);
});
console.log('end');

该示例中,Promise的执行流程:

  1. 首先输出“start”,接着执行Promise构造函数中的代码,输出“promise start”。
  2. 调用setTimeout函数,将回调函数异步加入任务队列,会异步执行回调函数。
  3. 输出“end”。
  4. 等待1秒后,从异步队列中读取回调函数,resolve Promise,将Promise对象标记为fulfill状态,同时执行then方法中的回调函数,输出“promise then:promise callback”。

1.3 await/async

async/await是ES8中的特性,比Promise更为优雅,在异步编程中经常被使用。async/await的实现原理就是Promise。

示例:

console.log('start');

function promise() {
  return new Promise((resolve, reject) => {
    console.log('promise start');
    setTimeout(() => {
      resolve('promise callback');
    }, 1000);
  });
}

async function asyncFunction() {
  let res = await promise();
  console.log('async function:', res);
}

asyncFunction();

console.log('end');

该示例中,async/await的执行流程:

  1. 首先输出“start”,接着执行promise函数中的代码,输出“promise start”。
  2. 调用setTimeout函数,将回调函数异步加入任务队列,会异步执行回调函数。
  3. 输出“end”。
  4. 等待1秒后,从异步队列中读取回调函数,resolve Promise,将Promise对象标记为fulfill状态。
  5. await promise()执行完毕后,执行async函数中的后续代码,输出“async function:promise callback”。

2. JS事件循环机制

JS的事件循环机制是负责读取异步队列中的回调函数,并在合适的时间将其加入调用栈中,执行回调函数。

2.1 微任务

微任务包含Promise回调函数、Node.js中的process.nextTick函数以及MutationObserver回调函数等,微任务中的回调函数执行速度比较快。

示例:

Promise.resolve().then(() => {
  console.log('promise callback 1');
}).then(() => {
  console.log('promise callback 2');
});

process.nextTick(() => {
  console.log('process.nextTick callback');
});

console.log('start');

该示例中,输出顺序为:

  1. start
  2. process.nextTick callback
  3. promise callback 1
  4. promise callback 2

2.2 宏任务

宏任务包含定时器回调函数、事件回调函数等,宏任务执行速度较慢。

示例:

console.log('start');

setTimeout(() => {
  console.log('setTimout callback');
}, 0);

Promise.resolve().then(() => {
  console.log('promise callback 1');
}).then(() => {
  console.log('promise callback 2');
});

console.log('end');

该示例中,输出顺序为:

  1. start
  2. end
  3. promise callback 1
  4. promise callback 2
  5. setTimout callback

3. JS代码执行顺序的总结

JS代码执行时:

  1. 如果遇到异步操作,则将回调函数加入异步队列中。
  2. 当同步代码执行完毕后,调用栈为空,JS引擎会读取异步队列中的回调函数,按照事件循环机制的规则取出执行。
  3. 执行完毕后,再次读取异步队列中的回调函数,如此反复,直到异步队列为空。

注意:代码的执行顺序不是绝对的,各种环境的实现可能会有所不同。

4. 小结

JS的异步执行需要遵守事件循环机制,异步操作将会加入异步队列,在适当的时间由任务队列中的事件循环机制调用栈中执行。虽然JS是单线程执行,但异步编程使代码的执行更为优雅和高效。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js 程序执行与顺序实现详解 - Python技术站

(0)
上一篇 4天前
下一篇 4天前

相关文章

  • JavaScript通过filereader接口读取文件

    下面详细讲解JavaScript通过filereader接口读取文件的完整攻略: 1. Filereader介绍 FileReader是H5新增的文件读取对象,通过FileReader对象,web应用程序可以异步读取存储在用户计算机上的文件内容,使用FileReader可以读取文本、图片(base64字符串)、音频和视频等格式的文件。下面我们将介绍如何利用F…

    JavaScript 4天前
    00
  • JS入门代码集合第2/4页

    关于“JS入门代码集合第2/4页”的完整攻略,我会步步为营地进行说明。 标题 首先,我们需要规范文章的结构,例如使用不同级别的标题来划分不同的段落。在这里,我们可以使用一、二级标题,例如: JS入门代码集合第2/4页完整攻略 一级标题示例 二级标题示例 代码块 其次,在讲解JS代码之前,我们需要知道如何展示JS代码。这里我们可以使用代码块,例如: conso…

    JavaScript 2023年5月17日
    00
  • 浅谈js常用内置方法和对象

    浅谈JS常用内置方法和对象 在JavaScript中,有很多常用的内置方法和对象。这些方法和对象可以帮助我们更加方便的处理数据以及进行各种操作。下面将详细讲解其中一些常用的方法和对象。 数组常用方法 JavaScript中的数组是一个非常重要的数据结构,常用的方法包括: push:在数组末尾添加一个或多个元素 javascript let arr = [1,…

    JavaScript 4天前
    00
  • JS弹性运动实现方法分析

    JS弹性运动实现方法分析 弹性运动的基本概念 我们经常使用动画效果来增强网站的视觉效果和用户体验。弹性动画效果指的是元素在运动时有一个缓冲过程,动画结束位置不是到达目标位置,而是反弹一段距离再停止。这种效果可以使我们的动画看起来更加自然、生动有趣。 JS实现弹性运动 为了实现弹性运动,我们需要用到三个变量:初始值、目标值和速度值。我们可以使用JS实现弹性运动…

    JavaScript 3天前
    00
  • JavaScript定时器用法

    JavaScript定时器是一种用于在指定时间间隔后执行代码的功能。在Web应用程序中,它们经常用于将动画效果与其他用户交互部分结合起来。本攻略将详细介绍JavaScript定时器,包括setTimeout和setInterval函数的用法。 setTimeout setTimeout函数允许我们在指定的时间间隔之后执行一段代码。以下是setTimeout函…

    Web开发基础 2023年3月30日
    00
  • JS实现页面炫酷的时钟特效示例

    下面我将详细讲解如何使用JS实现页面炫酷的时钟特效。 第一步:HTML结构 首先,在HTML中创建一个时钟的容器,可以使用<div>标签包裹起来,为其添加一个id属性,以便JS能够准确定位到该元素。 <div id="clock"></div> 第二步:CSS样式 接着,为时钟容器添加CSS样式。我们可…

    JavaScript 4天前
    00
  • jQuery基础教程笔记适合js新手第1/2页

    首先需要明确的是,”jQuery基础教程笔记适合js新手”指的是一篇博客或教程文章,因此在进行攻略之前,需要先打开这篇文章并仔细阅读,了解其涵盖的内容和需要掌握的知识点。 在阅读完整篇文章后,接下来可以进行以下步骤: 理解jQuery的基本概念和用法 jQuery是一种JavaScript库,用于简化HTML文档操作、处理事件、动画效果、AJAX等操作。在攻…

    JavaScript 2023年5月18日
    00
  • JavaScript中7种位运算符在实战的妙用

    我们知道,在 JavaScript 中,有7种位运算符号,分别是按位与(&)、按位或(|)、按位异或(^)、左移位(<<)、有符号右移(>>)、无符号右移(>>>)、以及取反(~)。这些运算符虽然不像加减乘除一样常见,在实际开发中却有着广泛的应用。下面我们将讲解这7种运算符在实战中的应用,并用具体的示例进行说…

    JavaScript 3天前
    00
  • javaScript中Math()函数注意事项

    Math()函数是JavaScript语言中的一个内置对象,提供了很多数学相关的工具方法。在使用Math()函数时,有一些需要注意的细节和注意事项。 1. Math()函数使用注意事项 1.1 获取随机数 获取随机数是Math()函数最常用的功能之一。使用Math()函数生成随机数时,需要注意以下两个问题。 随机数生成公式:Math.random() * (…

    JavaScript 3天前
    00
  • 简单介绍JavaScript的变量和数据类型

    当我们在编写JavaScript程序时,变量和数据类型是经常需要用到的概念,下面就来详细讲解一下。 基本概念 变量 变量是用来存储数据的容器,可以通过使用变量名来引用这些数据。JavaScript中的变量声明可以使用 var、let、const 等关键字来完成,其中 var 关键字是早期版本的语法,let 和 const 关键字是ES6中新增的。 数据类型 …

    JavaScript 4天前
    00