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

yizhihongxing

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)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • JavaScript实现网页截图功能

    实现网页截图功能需要使用到JS的API,其中最主要的是使用html2canvas和canvas2image两个JS库,并且需要遵循跨域访问的规则。下面是实现网页截图功能的完整攻略: 步骤一:引入必要的JS库 在html文件中的head中引入下列两个JS库: <script src="https://cdn.bootcdn.net/ajax/l…

    JavaScript 2023年5月19日
    00
  • js实现轮播图效果 纯js实现图片自动切换

    下面我将为您详细讲解如何使用纯js实现轮播图效果,并提供两个示例。 轮播图效果的实现 核心思路 实现轮播图效果,主要的核心思路是使用定时器(setInterval)对图片进行自动切换,并且在用户触发左右切换按钮时进行图片的手动切换。 具体来说,实现图片的自动切换需要以下步骤: 获取图片容器和图片列表的宽度、当前图片的索引 使用定时器不断地切换图片,每隔一定的…

    JavaScript 2023年6月11日
    00
  • 详解javascript高级定时器

    详解JavaScript高级定时器 在JavaScript中,定时器是一种非常强大的机制,它允许你在未来的某个时间点执行某些代码。在本文中,我们将探讨JavaScript高级定时器的各种用法和技巧。 setTimeout setTimeout允许你在一定的延迟之后执行一段代码。语法如下: setTimeout( function() { // 在这里写需要执…

    JavaScript 2023年6月11日
    00
  • 从0到1搭建element后台框架优化篇(打包优化)

    那我来详细讲解一下从0到1搭建element后台框架优化篇中的打包优化。 简介 打包优化是在项目上线前必须进行的重要操作之一,它可以优化项目的加载速度和性能,提升用户体验。在本篇文章中,我们将通过一些实例来介绍如何对 element 后台框架进行打包优化。 优化策略 在进行打包优化时,我们通常采用以下策略: 按需加载:将不常用的组件或库进行按需加载,减少文件…

    JavaScript 2023年6月10日
    00
  • element-ui 上传图片后标注坐标点

    下面将详细讲解“element-ui上传图片后标注坐标点”的完整攻略。 准备工作 安装 element-ui 组件库和 vue-cropperjs 图片裁剪插件。 npm install element-ui vue-cropperjs –save 引入 element-ui 中的 Upload 和 Dialog 组件。 <template> …

    JavaScript 2023年6月10日
    00
  • JavaScript数据类型相关知识详解

    JavaScript数据类型相关知识详解 在JavaScript中,数据类型可以分为基本数据类型和复杂数据类型。本篇攻略将详细讲解每种数据类型和其相关知识点。 基本数据类型 Number JavaScript中的Number类型可以表示整数和浮点数。在JavaScript中,Number类型可以进行四则运算和比较运算。 整数 JavaScript中的整数范围…

    JavaScript 2023年5月18日
    00
  • asp.net简单实现页面换肤的方法

    下面是“ASP.NET简单实现页面换肤的方法”的完整攻略: 第一步:准备工作 打开 Visual Studio,创建一个 ASP.NET Web 应用程序。 在项目中添加所需要的主题皮肤文件夹,比如:theme1、theme2。 第二步:设置样式 在 theme1 文件夹中,创建 main.css 文件,并添加相应的样式。 在 theme2 文件夹中,创建 …

    JavaScript 2023年6月10日
    00
  • 图片动画横条广告带上下滚动的JS代码

    下面我来为你详细讲解如何实现“图片动画横条广告带上下滚动的JS代码”。 1. 准备工作 在开始编写代码之前,首先需要准备好以下内容: 在HTML页面中添加一个容器元素,以放置广告内容。 在CSS样式中,设置容器元素的宽度、高度和背景颜色。 准备好需要展示的广告图片,可以通过链接或直接将图片存放在本地。 编写JS代码来实现图片滚动效果。 2. 实现思路 要实现…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部