likes
comments
collection
share

你会Promise我给你解释什么是promise吗

作者站长头像
站长
· 阅读数 22

JavaScript中的Promise语法

JavaScript Promise与事件循环机制深度解析

在现代JavaScript编程中,Promise无疑是一个核心概念,它极大地改善了异步编程模型,使得处理异步操作变得更加优雅、可读性强。而这一切高效运行的背后,离不开JavaScript的事件循环(Event Loop)机制。本文旨在深入探讨Promise的工作原理及其与事件循环的关系,同时通过实例解析,帮助读者全面理解这两者如何协同工作,以构建高效、可靠的异步应用。

JavaScript的单线程特性与异步需求

JavaScript作为浏览器和Node.js平台的主要编程语言,其设计之初就选择了单线程模型。这意味着,在任何给定时间,JavaScript只能执行一个任务。这对于避免复杂的并发问题、保证数据安全有着天然的优势,但也带来了处理耗时操作(如文件I/O、网络请求)时的挑战,因为这些操作如果在主线程上直接执行,将会阻塞其他任务,影响用户体验。

为了解决这一矛盾,JavaScript引入了异步编程模型,其中事件循环机制扮演着核心角色,而Promise则是这一模型中用于组织和管理异步操作的关键工具。

事件循环机制概览

事件循环是JavaScript运行环境(如浏览器或Node.js)的核心机制,负责调度任务的执行。其基本流程如下:

  1. 宏任务:包括整体脚本执行、setTimeout、setInterval、setImmediate等。
  2. 微任务:包括Promise的回调、MutationObserver、process.nextTick等。

执行流程简述:

  • 初始化:首先执行全局脚本,这是一个宏任务。
  • 检查微任务队列:每当一个宏任务执行完毕,事件循环会检查是否存在待执行的微任务,如果有,则全部执行完后再继续下一个宏任务。
  • 宏观调度:宏任务执行完毕且所有微任务处理完成,事件循环会再次从宏任务队列中取出下一个任务执行,如此循环往复。

Promise的诞生与使用

Promise是为了解决回调地狱(Callback Hell)问题而生的。它代表一个异步操作的最终完成(或失败),并提供了一种链式调用的方式来组织异步代码,使得代码更加清晰、易于理解和维护。

  • Promise状态:Pending(进行中)、Resolved(已成功,又称Fulfilled)、Rejected(已失败)。

  • 基本用法

    const promise = new Promise((resolve, reject) => {
        // 异步操作
    });
    promise.then(
        value => { /* 处理成功情况 */ },
        reason => { /* 处理失败情况 */ }
    );
    
  • 链式调用.then.catch方法返回一个新的Promise,使得多个异步操作能够按顺序执行,且能优雅地处理错误。

当创建一个Promise时,其内部的异步操作(如setTimeout)会被安排到宏任务队列。当Promise的状态从Pending变为Resolved或Rejected时,其注册的.then.catch回调(即微任务)会被加入到微任务队列中等待执行。

function xq() {
    return new Promise(resolve => setTimeout(() => {
        console.log('选专业');
        resolve();
    }, 2000));
}

xq().then(() => {
    console.log('大一');
}).then(() => {
    console.log('大二');
});

你会Promise我给你解释什么是promise吗 在上述代码中,xq函数返回的Promise在2秒后变为Resolved,其后跟的.then回调作为微任务被加入到队列,等待当前宏任务执行完毕后立即执行,从而保证了代码的顺序执行效果。

尝试不用Promise的执行函数,二者进行对比

以下是取消Promise方法的截图

function xq() {
    return new Promise(resolve => setTimeout(() => {
        console.log('选专业');

    }, 2000));
}

xq().then(() => {
    console.log('大一');
}).then(() => {
    console.log('大二');
});

你会Promise我给你解释什么是promise吗

取消.then()的使用

function xq() {
    return new Promise(resolve => setTimeout(() => {
        console.log('选专业');
        resolve();
    }, 2000));
}

xq().then(() => {
    console.log('大一');
})
    console.log('大二');

你会Promise我给你解释什么是promise吗

我们要重视其中的resolve()函数的执行,如果没有更改promis的状态,则会默认不执行函数

  1. 初始宏任务:脚本开始执行,创建并立即执行xq函数,此时Promise处于Pending状态,内部的setTimeout被安排到宏任务队列。

  2. 第一个宏任务结束:脚本主体执行完毕,开始检查微任务队列(此时为空),然后执行宏任务队列中的setTimeout,xq的Promise变为Resolved。

  3. 微任务执行:Promise变为Resolved后,其关联的.then回调作为微任务被加入微任务队列。当前宏任务执行完毕后,检查微任务队列,执行console.log('大一')

  4. 后续微任务处理:第一个.then中的回调执行完毕后,紧跟的第二个.then回调同样作为微任务加入队列,并立即执行,输出'大二'

转载自:https://juejin.cn/post/7385801028941660169
评论
请登录