promise学习笔记

一、什么是异步编程

JavaScript 异步编程是 处理长时间运行的任务而不会阻塞主线程的一种方式 。JavaScript 是单线程的,这意味着一次只能执行一个任务。异步编程允许程序在等待耗时操作(如网络请求、文件读取、计时器等)完成时继续执行其他任务。

二、JS中异步编程有哪些方法

1、回调函数(callback)

回调函数是一种特殊的函数,它作为参数传递给另一个函数,并在被调用函数执行完毕后被调用。回调函数是最基本的异步处理方式。

function fetchData(callback) {
    setTimeout(() => {
        const data = "Hello, World!";
        callback(data);
    }, 1000);
}

fetchData((data) => {
    console.log(data);  
});

2、Promise

Promise 是一个表示异步操作最终完成或失败的对象,并返回结果值。它提供了 .then().catch() 方法来处理成功和失败的回调。

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = "Hello, World!";
            resolve(data);
        }, 1000);
    });
}

fetchData().then((data) => {
    console.log(data); 
}).catch((error) => {
    console.error(error);
});

3、Async/Await

 async用于声明一个function是异步的,而await则可以认为是 async await的简写形式,是等待一个异步方法执行完成的。


async function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = "Hello, World!";
            resolve(data);
        }, 1000);
    });
}

async function printData() {
    try {
        const data = await fetchData();
        console.log(data); 
    } catch (error) {
        console.error(error);
    }
}

printData();

4、事件循环

事件循环是单线程的JavaScript在处理异步事件时进行的一种循环过程。对于异步事件它会先加入到事件队列中挂起,等主线程空闲时会去执行事件队列中的事件。如此反复循环。事件循环的设计使得 JavaScript 可以在单线程下处理异步操作,避免了阻塞的情况,保证了程序的响应性和流畅性。

console.log("script start");

setTimeout(function() {
    console.log("setTimeout");
}, 0);

Promise.resolve().then(function() {
    console.log("promise1");
}).then(function() {
    console.log("promise2");
});

console.log("script end");

这段代码的运行结果:

script start
script end
promise1
promise2
setTimeout
  1. 首先输出 "script start"。
  2. 执行setTimeout,将"setTimeout"加入定时器队列。
  3. 执行Promise.resolve(),将第一个.then中的"promise1"加入微任务队列。
  4. 输出 "script end"。
  5. 执行第一个.then中的任务,输出 "promise1"。
  6. 执行第二个.then中的任务,输出 "promise2"。
  7. 最后执行定时器任务,输出 "setTimeout"。

三、promise的概念

Promise是一个构造函数,是异步编程的一种解决方案。Promise 是 ES6新引入的一个特性,它允许你在异步操作(如网络请求)完成后执行某些代码。它代表了一个将来才会知道结果的操作。他有三个状态:

  • Pending(进行中):初始状态,既没有成功,也没有失败。
  • Fulfilled(已成功):操作成功完成。
  • Rejected(已失败):操作失败。

而promise执行的过程,就是由pending到fulfilled和rejected的过程(不可逆

四、promise对比callback的优点

 1、解决了回调地狱问题: Promise 通过链式调用 then 方法的方式,避免了传统 callback 嵌套过多导致的回调地狱问题,使代码结构更加清晰和易于维护。

2、提供了更好的错误处理机制: Promise 提供了 catch 方法用于捕获链式调用中的错误,并且可以通过 Promise.all 或 Promise.race 等方法进行多个异步操作的错误处理。

3、支持并发和串行的异步操作: Promise 可以通过 Promise.all 和 Promise.race 来管理多个异步操作的并发执行或串行执行,使得复杂的异步操作更加容易管理。

4、状态管理更清晰: Promise 的状态包括 pending、fulfilled 和 rejected,状态的切换更加明确,便于跟踪和处理异步操作的状态。

5、更容易进行异步操作的组合: Promise 的 then 方法返回一个新的 Promise 对象,可以方便地进行异步操作的组合和串联,提高了代码的可读性和可维护性。

五、.then的链式调用和多次调用同一个promise.then的结果

1、.then的链式调用

在 Promise 中,每次调用 .then() 方法都会返回一个新的 Promise 对象,因此可以进行链式调用。链式调用的每一个 .then() 方法都可以处理上一个 .then() 方法返回的 Promise 对象的结果。链式调用可以使代码更加清晰和易读,便于处理异步操作的结果。

myPromise.then(func1)
         .then(func2)
         .then(func3);

2、.then的多次调用

当多次调用同一个 promise.then() 方法时,之前的 .then() 方法会捕获并处理前一个 .then() 方法返回的 Promise 对象的结果。如果同一个 promise.then() 被多次调用,那么每次调用的处理函数会在 Promise 状态改变时都会被执行。这种方式可以用于多个处理逻辑需要同时应用在同一个 Promise 结果上的情况。

const myPromise = new Promise((resolve, reject) => {
    resolve("Hello");
});

myPromise.then(result => console.log(result));
myPromise.then(result => console.log(result.toUpperCase()));

总结:链式调用 .then() 返回的每个 Promise 对象都可以单独处理结果,而多次调用同一个 promise.then() 会共享同一个 Promise 对象的结果。

六、promise实例上的方法有哪些

1、then():接收两个函数作为参数,第一个函数在 Promise 成功时调用,第二个在失败时调用。

// 创建一个 Promise 对象,模拟异步操作
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const randomNumber = Math.random();
        if (randomNumber > 0.5) {
            resolve(randomNumber); // 成功时调用 resolve
        } else {
            reject("Failed"); // 失败时调用 reject
        }
    }, 1000);
});

// 使用 Promise 的 then 方法处理成功和失败的情况
myPromise.then(result => {
    console.log("Resolved with result: " + result);
}).catch(error => {
    console.log("Rejected with error: " + error);
}).finally(() => {
    console.log("Promise is settled"); // 无论成功或失败都会执行
});
2、catch():用于捕获 Promise 中发生的错误,catch的优先级低于then的第二个参数,最主要用于多个promise的错误统一处理。
// 创建一个 Promise 对象,模拟异步操作
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const randomNumber = Math.random();
        if (randomNumber > 0.5) {
            resolve(randomNumber); // 成功时调用 resolve
        } else {
            reject("Failed"); // 失败时调用 reject
        }
    }, 1000);
});

// 使用 Promise 的 catch 方法捕获 Promise 对象状态改变时的错误
myPromise.then(result => {
    console.log("Resolved with result: " + result);
}).catch(error => {
    console.log("Rejected with error: " + error); // 捕获并处理错误
}).finally(() => {
    console.log("Promise is settled"); // 无论成功或失败都会执行
});

3、finally():无论 Promise 最终状态如何都会执行。

// 创建一个 Promise 对象,模拟异步操作
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const randomNumber = Math.random();
        if (randomNumber > 0.5) {
            resolve(randomNumber); // 成功时调用 resolve
        } else {
            reject("Failed"); // 失败时调用 reject
        }
    }, 1000);
});

// 使用 Promise 的 finally 方法,在 Promise 对象状态改变时都会执行的回调函数
myPromise.then(result => {
    console.log("Resolved with result: " + result);
}).catch(error => {
    console.log("Rejected with error: " + error); // 捕获并处理错误
}).finally(() => {
    console.log("Promise is settled"); // 无论成功或失败都会执行
});

七、promise的静态方法有哪些

1、Promise.all()等待所有的 Promise 完成,有任一失败则失败。

// 使用 Promise.all 来处理多个 Promise 对象
const promise1 = Promise.resolve("Promise 1");
const promise2 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("Promise 2");
    }, 2000);
});

Promise.all([promise1, promise2]).then(values => {
    console.log("All promises resolved with values: ", values);
});

2、Promise.race():返回最先改变状态的 Promise 的结果。

// 使用 Promise.race 来处理多个 Promise 对象
const racePromise1 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("Race Promise 1");
    }, 1000);
});

const racePromise2 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("Race Promise 2");
    }, 500);

Promise.race([racePromise1, racePromise2]).then(value => {
    console.log("The first promise to resolve is: ", value);
});

3、Promise.allSettled() 不管所有的 Promise 是成功还是失败,都会等待所有的 Promise 都有一个结果后才会返回。返回的结果是每个 Promise 的状态和结果。

// 使用 Promise.allSettled 来处理多个 Promise 对象,无论成功或失败都会返回结果
const settledPromise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Settled Promise 1");
    }, 1500);
});

const settledPromise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("Settled Promise 2 failed");
    }, 1000);
});

Promise.allSettled([settledPromise1, settledPromise2]).then(results => {
    console.log("All promises settled with results: ", results);
});

4、Promise.any()它在传入的可迭代对象中的任意一个 Promise 成功时解决,并返回第一个解决的 Promise 的值。如果传入的可迭代对象中的所有 Promise 都失败了,则返回一个拒绝的 Promise,其中包含一个 AggregateError,包含所有失败的 Promise 的原因

// 使用 Promise.any 来处理多个 Promise 对象,只要有一个成功就返回
const anyPromise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("Any Promise 1 failed");
    }, 1500);
});

const anyPromise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Any Promise 2");
    }, 1000);
});

Promise.any([anyPromise1, anyPromise2]).then(value => {
    console.log("The first promise to resolve is: ", value);
}).catch(errors => {
    console.log("All promises were rejected with errors: ", errors);
});

5、Promise.resolve()Promise.reject():快速创建已解决或已拒绝的 Promise。

// 使用 Promise.resolve 返回一个 resolved 的 Promise 对象
const resolvedPromise = Promise.resolve("Resolved value");

// 使用 Promise.reject 返回一个 rejected 的 Promise 对象
const rejectedPromise = Promise.reject("Rejected reason");

八、静态方法如何定义

在静态方法中,返回一个Promise对象,通过setTimeout模拟异步操作,并在1秒后通过resolve方法返回结果。

class MyClass {
    static staticMethod() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("This is a static method");
            }, 1000);
        });
    }
}

MyClass.staticMethod().then(result => {
    console.log(result); 
});

九、实例上的方法如何定义

在实例方法中,我们返回一个Promise对象,通过setTimeout模拟异步操作,并在1秒后通过resolve方法返回带有实例属性name的结果。

class MyClass {
    constructor(name) {
        this.name = name;
    }

    instanceMethod() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("Hello, my name is " + this.name);
            }, 1000);
        });
    }
}

const myInstance = new MyClass("Alice");
myInstance.instanceMethod().then(result => {
    console.log(result); 
});

十、创建一个promise

// 创建一个 Promise 对象
const myPromise = new Promise((resolve, reject) => {
    // 在 Promise 内部进行异步操作
    setTimeout(() => {
        const randomNumber = Math.random();
        if (randomNumber > 0.5) {
            resolve(randomNumber); // 成功时调用 resolve
        } else {
            reject("Promise rejected"); // 失败时调用 reject
        }
    }, 1000);
});

// 使用 then 方法处理 Promise 的 resolve 结果
myPromise.then(result => {
    console.log("Resolved with result: " + result);
}).catch(error => {
    console.log("Rejected with error: " + error); // 捕获并处理错误
});

创建了一个Promise对象myPromise,传入一个executor函数,该函数接受两个参数resolvereject。在executor函数内部,我们使用setTimeout模拟异步操作,1秒后生成一个随机数,如果随机数大于0.5,则调用resolve方法并传入随机数作为成功的结果;如果随机数小于等于0.5,则调用reject方法并传入错误信息作为失败的原因。然后我们使用then方法来处理Promise的resolve结果,并使用catch方法来捕获并处理Promise的reject结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值