promise


提示:以下是本篇文章正文内容,下面案例可供参考
Promise 是 JavaScript 中用于处理异步操作的一种对象。它表示一个异步操作的最终完成(或失败)及其结果值。Promise 提供了一种更清晰、更结构化的方式来处理异步代码,相较于传统的回调函数,它避免了回调地狱的问题。

一、基本概念

一个 Promise 对象有以下几个状态:

  1. pending:初始状态,既不是成功也不是失败状态。
  2. fulfilled:操作成功完成。
  3. rejected:操作失败。

一旦 Promise 状态从 pending 转变为 fulfilledrejected,它就会保持这个状态,不会再改变。这称为 Promise 的“不可变性”。

二、使用步骤

1.创建一个 Promise

通过 new Promise 构造函数创建一个 Promise 对象:
代码如下(示例):

const myPromise = new Promise((resolve, reject) => {
    // 执行一些异步操作,例如一个异步请求
    //resolve函数的作用:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
    //reject函数的作用:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
    setTimeout(() => {
        const success = true; // 这是一个示例条件
        if (success) {
            resolve('Operation successful'); // 操作成功
        } else {
            reject('Operation failed'); // 操作失败
        }
    }, 1000);
});

2.使用 then 和 catch

可以使用 then 方法来指定当 Promise 成功时要执行的回调函数,使用 catch 方法来指定当 Promise 失败时要执行的回调函数。
代码如下(示例):

myPromise
    .then(result => {
        console.log(result); // 输出: Operation successful
    })
    .catch(error => {
        console.error(error); // 输出: Operation failed
    });

3.使用 finally

finally 方法用于指定不论 Promise 最终状态如何都会执行的回调函数,用于进行一些清理操作。
代码如下(示例):

myPromise
    .then(result => {
        console.log(result);
    })
    .catch(error => {
        console.error(error);
    })
    .finally(() => {
        console.log('Cleanup'); // 总会执行
    });

4.使用 Promise.all

Promise.all:当所有的 Promise 都成功时才会成功,如果其中任何一个 Promise 失败,则整个 Promise.all 失败。
代码如下(示例):

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(values => {
  console.log(values); // [3, 42, "foo"]
});

5.使用 Promise.race

Promise.race:只要有一个 Promise 成功或失败,就会立即返回那个 Promise 的结果,并且不管其他 Promise 是否完成。
代码如下(示例):

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then(value => {
  console.log(value); // "two"
});

三、执行顺序

在 JavaScript 中,Promise 的执行顺序遵循以下规则:

  1. 同步执行:Promise 的执行是同步的,new Promise 会立即执行其传入的执行器函数,而不会等待当前执行栈中的代码执行完毕。

  2. 异步操作:Promise 的执行器函数中通常包含异步操作,比如异步请求、定时器等。这些异步操作不会阻塞 Promise 的执行,而是会继续执行后续的代码。

  3. then 方法:当 Promise 对象的状态发生变化(从 pending 变为 fulfilled 或 rejected),会调用与之对应的 then 或 catch 方法中注册的回调函数。

  4. 微任务队列then 和 catch 注册的回调函数属于微任务,它们会在当前宏任务执行完毕后立即执行。如果有多个 then 或 catch 方法,它们的回调函数会按照注册的顺序依次执行。

  5. Promise 链:如果在一个 then 方法中返回了一个新的 Promise 对象,则该 Promise 链会继续执行,新的 Promise 对象的状态变化会触发后续的 then 或 catch 方法中的回调函数执行。

  6. 其他微任务和宏任务:在 then 或 catch 回调函数执行完毕后,还可能存在其他微任务(比如 process.nextTick、MutationObserver)和宏任务(比如定时器、I/O 操作)需要执行。

综上所述,Promise 的执行顺序可以概括为:同步执行 Promise 构造函数中的执行器函数 => 异步操作继续执行 => 执行 then 或 catch 注册的回调函数 => 继续执行后续的微任务和宏任务
注:当同步代码执行完毕后,就会执行所有的宏任务,宏任务执行完成后,会判断是否有可执行的微任务;如果有,则执行微任务,完成后,执行宏任务;如果没有,则执行新的宏任务,形成事件循环。

四、示例

1.异步请求

代码如下(示例):

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { some: 'data' };
            const success = true; 
            if (success) {
                resolve(data);
            } else {
                reject('Error fetching data');
            }
        }, 2000);
    });
}

fetchData()
    .then(data => {
        console.log('Data received:', data); // 输出: Data received: { some: 'data' }
    })
    .catch(error => {
        console.error(error); // 例如:Error fetching data
    });

2.执行顺序

console.log('Start'); // 同步代码1  1

const promise1 = new Promise((resolve, reject) => {
    console.log('Promise1 Executor Start'); // 同步代码2  2
    setTimeout(() => {
        resolve('Promise1 Resolved');
        console.log('Promise1 Timer Finished'); // 异步代码1  10
    }, 1000);//1s后执行
    console.log('Promise1 Executor End'); // 同步代码3  3
});

promise1.then(value => {
    console.log(value); // 异步代码2 -> 微任务1  11
});

console.log('After Promise1'); // 同步代码4  4

const promise2 = new Promise((resolve, reject) => {
    console.log('Promise2 Executor Start'); // 同步代码5  5
    setTimeout(() => {
        resolve('Promise2 Resolved');
        console.log('Promise2 Timer Finished'); // 异步代码3  8
    }, 500);//0.5s后执行
    console.log('Promise2 Executor End'); // 同步代码6  6
});

promise2.then(value => {
    console.log(value); // 异步代码4 -> 微任务2  9
});

console.log('End'); // 同步代码7  7

//输出结果
//Start
//Promise1 Executor Start
//Promise1 Executor End
//After Promise1
//Promise2 Executor Start
//Promise2 Executor End
//End
//Promise2 Timer Finished
//Promise2 Resolved
//Promise1 Timer Finished
//Promise1 Resolved

分析执行顺序:

  1. 同步代码执行:
    1. console.log(‘Start’); 输出:Start
    2. 执行 new Promise 构造函数中的同步部分:
      1. console.log(‘Promise1 Executor Start’); 输出:Promise1 Executor Start
      2. setTimeout 注册一个定时器(1秒后执行)
      3. console.log(‘Promise1 Executor End’); 输出:Promise1 Executor End
    3. console.log(‘After Promise1’); 输出:After Promise1
    4. 执行 new Promise 构造函数中的同步部分:
      1. console.log(‘Promise2 Executor Start’); 输出:Promise2 Executor Start
      2. setTimeout 注册一个定时器(0.5秒后执行)
      3. console.log(‘Promise2 Executor End’); 输出:Promise2 Executor End
      4. console.log(‘End’); 输出:End
  2. 异步代码执行:
    1. 0.5秒后,Promise2 的定时器触发:
      1. resolve(‘Promise2 Resolved’) 将 promise2 状态变为 fulfilled
      2. console.log(‘Promise2 Timer Finished’); 输出:Promise2 Timer Finished
      3. promise2.then 注册的回调被推入微任务队列
    2. 1秒后,Promise1 的定时器触发:
      1. resolve(‘Promise1 Resolved’) 将 promise1 状态变为 fulfilled
      2. console.log(‘Promise1 Timer Finished’); 输出:Promise1 Timer Finished
      3. promise1.then 注册的回调被推入微任务队列
  3. 微任务执行:
    1. 执行 promise2.then 注册的回调:
      console.log(‘Promise2 Resolved’); 输出:Promise2 Resolved
    2. 执行 promise1.then 注册的回调:
      console.log(‘Promise1 Resolved’); 输出:Promise1 Resolved

总结

Promise 是现代 JavaScript 中处理异步操作的核心内容,通过它可以让异步代码更加清晰易读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值