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

相关文章

  • 清除WKWebView cookies的方法

    当我们使用WKWebView加载网页时,有时候需要清除已有的cookies。下面我将详细讲解清除WKWebView cookies的方法。 1. 使用HTTPCookieStorage清除 可以使用HTTPCookieStorage类来清除cookies。这个类是管理存储在客户端的http cookies的一个单例类。下面是代码示例: //得到单例对象 le…

    JavaScript 2023年6月11日
    00
  • 很全面的JavaScript常用功能汇总集合

    欢迎来到网站,以下是“很全面的JavaScript常用功能汇总集合”的完整攻略。 什么是JavaScript常用功能汇总集合 JavaScript常用功能汇总集合是一个包含了常见的JavaScript功能和代码示例的集合,涵盖了诸如数组操作、字符串处理、函数式编程、事件处理等常用功能。通过本集合,您可以快速地获取JavaScript开发过程所需的绝大部分基础…

    JavaScript 2023年5月18日
    00
  • js获取当前时间显示在页面上并每秒刷新

    获取并显示当前时间是前端常见的需求之一。本文将提供一种基于JavaScript的实现方案,通过一个完整的示例演示如何实现“js获取当前时间显示在页面上并每秒刷新”。 方案概述 我们将使用JavaScript的Date对象获取当前时间,并将获取到的时间展示在网页上。为了实现每秒刷新,我们需要使用JavaScript中的定时器setInterval()函数。 具…

    JavaScript 2023年5月27日
    00
  • 使用firebug进行调试javascript的示例

    使用 Firebug 进行调试 JavaScript 是前端开发中非常常见的操作之一,下面是一个完整的攻略过程,包括如何安装和使用 Firebug 进行调试 JavaScript 的示例说明: 安装 Firebug 若要使用 Firebug 进行调试 JavaScript,首先要安装 Firebug 扩展,具体操作步骤如下: 打开 Firefox 浏览器,点…

    JavaScript 2023年6月10日
    00
  • JavaScript格式化数字的函数代码

    下面是详细讲解“JavaScript格式化数字的函数代码”的完整攻略。 什么是JavaScript格式化数字? JavaScript格式化数字的作用在于将数字按照一定的规则格式化为易于识别的格式。比如添加千位分隔符,设定小数点位数,设定前缀或后缀等等。 代码实现 下面通过个人的经验,总结了三种实现方式。 方式一:使用正则表达式 JavaScript格式化数字…

    JavaScript 2023年5月27日
    00
  • JS实现回到页面顶部动画效果的简单实例

    下面我将为你详细讲解“JS实现回到页面顶部动画效果的简单实例”的完整攻略。 步骤1:HTML结构 首先,在页面中需要添加一个回到顶部的按钮。在 HTML 中添加一个 button 元素,并为其添加一个 id 属性,以方便在 JS 中使用。 <button id="backToTopBtn">回到顶部</button&gt…

    JavaScript 2023年6月10日
    00
  • 使用JavaScript修改浏览器URL地址栏的实现代码

    使用JavaScript修改浏览器URL地址栏是一种在网站开发过程中比较常见的技术手段,可以使用户的浏览更加流畅,并且能够实现一些有趣的效果。下面是一个详细讲解如何使用JavaScript实现这个功能的攻略: 1. 实现方式 实现修改浏览器URL地址栏的方式有两种:一种是使用历史记录API,另一种是使用HTML5的pushState和replaceState…

    JavaScript 2023年6月11日
    00
  • JavaScript编写Chrome扩展实现与浏览器的交互及时间通知

    下面是详细讲解“JavaScript编写Chrome扩展实现与浏览器的交互及时间通知”的完整攻略。 1. 创建Chrome扩展 首先,我们需要创建一个Chrome扩展来实现与浏览器的交互和时间通知。在扩展文件夹中创建以下文件和文件夹: manifest.json:必须的扩展文件,其中包含了扩展的名称、描述、版本和其他元数据。 popup.html:扩展的弹出…

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