Promise及其应用

目录

一.Promise的原理

1.1promise原理:

1.2Promise的优点

1.3Promise的缺点

二.Promise的状态

2.1 pending

2.2 fulfilled

2.3 rejected

三.async/await

3.1 概念

3.2 原理

3.3 作用

3.4 用法

3.5 应用场景

四.异步编程与Promise的关系

4.1 相同点

4.2 区别

五.Promise的创建

5.1创建Promise对象

5.2Promise链式调用

六.Promis使用方法

6.1.Promise原型对象的方法

6.1.1  .then()

6.1.2  .catch()

6.1.3  .finally()

6.2Promise构造函数的方法

6.2.1 Promise.resolve()

6.2.2 Promise.reject()

6.2.3 Promise.all()

6.2.4 Promise.race()

七.Promise在实际场景中的应用


一.Promise的原理

1.1promise原理:

Promise是JavaScript中一种异步编程的解决方案,用于解决回调地狱和代码可读性差的问题。它是一个包装了异步操作的对象,可以让我们更优雅、清晰地处理异步操作。

1.2Promise的优点

优化了异步操作的流程控制,避免了回调地狱和嵌套的回调函数。

可以更好地处理异步操作的状态和结果,使代码更加清晰、简洁。

可以使用Promise.all()方法和Promise.race()方法来处理多个异步操作的结果,进一步简化异步编程的过程。

1.3Promise的缺点

对于初学者来说,可能需要一些时间来理解Promise的概念和使用方法。

需要在异步操作完成后手动调用resolve()或reject()方法,可能会出现遗漏或错误。

无法取消Promise,一旦创建就必须等待其状态发生变化。

在使用.then()方法链式调用多个Promise对象时,如果其中任意一个Promise对象发生错误,整个链式调用都会停止,需要使用.catch()方法来捕获错误。

二.Promise的状态

Promise对象有三种状态,分别为pending、resolved和rejected。Promise对象的状态只能从pending转变为resolved或rejected,一旦状态变化,就不会再改变。

2.1 pending

初始化状态,即Promise实例创建后的初始状态,既不是成功也不是失败状态。

2.2 fulfilled

操作成功的状态,这意味着Promise的一个操作已经成功完成。Promise对象的结果会传递给.then()方法注册的回调函数。

"resolved"可能是对"fulfilled"状态的一个普遍误解,因为一个"resolved"的Promise可能是"fulfilled"或者"rejected"。

2.3 rejected

意味着异步操作失败,Promise对象的错误会传递给.catch()方法注册的回调函数

三.async/await

3.1 概念

async/await是一种在JavaScript中处理异步操作的语法糖,它使得异步操作的代码看起来像是同步的代码,使得异步操作更加容易理解和对调试,同时也能够避免回调地狱。

3.2 原理

async/await是基于Promise实现的,async函数返回一个Promise对象,await可以等待一Promise对象的执行结果,如果该Promise对象是resolved状态,则返回其resolve的结果;如果该Promise对象是rejected状态,则抛出其reject的原因。

3.3 作用

async/await可以用于处理异步操作,提供了一种更加优雅的方式来处理异步代码。

3.4 用法

sync函数需要使用async关键字来声明,它可以包含多个await语句,await语句必须在async函数中使用,用来等待Promise对象的执行结果。使用async/await的代码看起来像是同步代码,但实际上是异步执行的

3.5 应用场景

async/await可以用于处理所有需要异步执行的场景,如网络请求、文件读写等操作。它特别适用于需要按照顺序执行多个异步操作的场景,可以避免回调地狱,提高代码的可读性和可维护性。

下面是一个使用async/await处理异步请求的示例

async function fetchData() {
  const response1 = await fetch('http://api.example.com/data1');
  const data1 = await response1.json();
  const response2 = await fetch('http://api.example.com/data2');
  const data2 = await response2.json();
  return { data1, data2 };
}

fetchData()
  .then(result => console.log(result))
  .catch(error => console.error(error));

上面的代码使用async/await处理了两个异步请求,等待每个请求的结果后再执行下一个请求,最终返回两个请求的结果。代码看起来像是同步执行的,但实际上是异步执行的。

在这个例子中,我们定义了一个async函数fetchData,它通过fetch函数异步获取数据,并使用await关键字等待数据获取完成。当数据获取完成后,我们再使用await关键字将response转换为json格式的数据,并打印出来。如果在获取数据的过程中出现了错误,我们使用.catch语句捕获错误并打印出来。

使用async/await可以让我们避免回调地狱和Promise链式调用的复杂性,使代码更加简洁易懂。

四.异步编程与Promise的关系

4.1 相同点

setTimeoutPromise都是JavaScript中用于管理异步代码的工具。

4.2 区别

setTimeoutPromise都是用于实现异步操作的机制,它们之间的区别在于

①setTimeout是一种基于回调函数的机制,它通过设置一个定时器,在一定时间后触发回调函数来实现异步操作。而Promise是一种基于状态的机制,它通过返回一个Promise对象,来表示异步操作的完成状态。

②setTimeout只能实现一次性的异步操作,且不具备错误处理机制,而Promise可以实现多次异步操作的串联和并行可以链式地处理多个异步操作,让代码变得更为清晰易读。另外还可以通过Promise的链式调用和async/await语法,可以更方便地管理异步操作的顺序和结果。

③Promise具有更多的功能和优势。比如Promise可以处理异步操作的异常情况,而setTimeout需要在回调函数中手动处理异常。Promise还可以通过.catch()方法捕获异常,并返回一个新的Promise对象来表示异常的处理结果。此外,Promise还可以实现异步操作的取消、超时控制等功能。

综上所述,虽然setTimeoutPromise都可以实现异步操作,但是Promise具有更强大的功能和更好的可维护性,因此在实际开发中,推荐使用Promise来管理异步操作。

五.Promise的创建

5.1创建Promise对象

在ES6中,可以使用Promise构造函数来创建一个Promise对象,构造函数接收一个参数——一个函数,这个函数有两个参数resolve和reject,分别表示异步操作成功和失败的回调函数。resolve函数会将Promise对象的状态从pending变成resolved,而reject函数则会将状态从pending变成rejected。

const promise = new Promise((resolve, reject) => {

  // 异步操作

  if (/* 异步操作成功 */) {

    resolve(result); // 改变Promise对象状态为resolved

  } else {

    reject(error); // 改变Promise对象状态为rejected

  }

});

5.2Promise链式调用

Promise对象的.then()方法可以为Promise对象注册成功的回调函数,.catch()方法可以为Promise对象注册失败的回调函数,可以链式调用多个.then()方法,也可以在链的最后使用.catch()方法处理错误。

promise.then((result) => {

// 处理异步操作成功的结果

return new Promise((resolve, reject) => {

// 进行更加复杂的异步操作

if (/* 操作成功 */) {

resolve(newResult);

} else {

reject(newError);

}

});

})

.then((newResult) => {

// 处理新的异步操作成功的结果

})

.catch((error) => {

// 处理错误

});

六.Promis使用方法

在 JavaScript 中,Promise 是一种用于异步编程的机制,它代表一个尚未完成但最终会完成的操作。在 Promise 中,有两个重要的概念:原型对象和构造函数。原型对象是指所有 Promise 实例共享的对象,其中定义了 then()、catch() 等方法,而构造函数则用于创建 Promise 对象的函数。

6.1.Promise原型对象的方法

Promise原型对象的方法有:then()、catch()、finally()。

6.1.1  .then()

.then() 方法注册一个回调函数,用于处理 Promise 成功状态的结果。它接受两个可选参数:成功回调函数和失败回调函数。如果一个回调函数没有被提供,它会被忽略。

例如:

const promise = new Promise((resolve, reject) => {

  resolve(42);

});



promise.then((result) => {

  console.log(result); // 输出 42

});

6.1.2  .catch()

.catch() 方法注册一个回调函数,用于处理 Promise 失败状态的结果。它接受一个参数:失败回调函数。

const promise = new Promise((resolve, reject) => {

  reject(new Error('Something went wrong'));

});



promise.catch((error) => {

  console.error(error.message); // 输出 "Something went wrong"

});

6.1.3  .finally()

.finally() 方法注册一个回调函数,无论 Promise 成功或失败都会执行该回调函数。它不接受任何参数。

例如:

const promise = new Promise((resolve, reject) => {

  resolve(42);

});



promise

  .then((result) => {

    console.log(result); // 输出 42

  })

  .finally(() => {

    console.log('Promise completed'); // 输出 "Promise completed"

  });

6.2Promise构造函数的方法

Promise构造函数的方法有:resolve()、reject()、all()、race()。

6.2.1 Promise.resolve()

Promise.resolve() 方法返回一个以给定值解析后的 Promise 对象。如果参数本身就是一个Promise 对象,那么 Promise.resolve() 方法会直接返回该对象,不会创建新的 Promise 对象。

语法:Promise.resolve(value)

参数:

value: 任何值

返回值:一个 Promise 对象

示例:

const myPromise = Promise.resolve('hello');

myPromise.then((value) => {

  console.log(value); // 输出 "hello"

});

const myOtherPromise = Promise.resolve(myPromise);

console.log(myPromise === myOtherPromise); // 输出 true

在上面的示例中,第一个 Promise.resolve() 方法返回一个解析为字符串 "hello" 的 Promise 对象。在 then() 方法中,可以打印该字符串。

第二个 Promise.resolve() 方法接收一个 Promise 对象作为参数。由于该参数已经是 Promise 对象,所以 Promise.resolve() 方法直接返回该对象,而不是创建一个新的 Promise 对象。因此,myPromise 和 myOtherPromise 变量引用的是同一个 Promise 对象,因此它们的值相等。

6.2.2 Promise.reject()

Promise.reject() 方法返回一个带有拒绝原因的 Promise 对象。

语法:Promise.reject(reason)

参数:

reason: 一个拒绝原因,通常是一个 Error 对象,但也可以是任何其他值

返回值:一个 Promise 对象,状态为拒绝状态,并且拒绝原因为给定的 reason 参数。

示例:

const myPromise = Promise.reject(new Error('Something went wrong!'));

myPromise.catch((error) => {

console.log(error.message); // 输出 "Something went wrong!"

});

在上面的示例中,Promise.reject() 方法返回一个带有拒绝原因的 Promise 对象,并且在 catch() 方法中可以捕获拒绝原因并打印出错误信息。

6.2.3 Promise.all()

Promise.all() 方法接收一个由 Promise 对象组成的数组作为参数,并返回一个新的 Promise 对象。当所有的 Promise 对象都变为解决状态时,该 Promise 对象的状态也变为解决状态,返回一个解决值数组,其中包含所有 Promise 对象的解决值。如果任何一个 Promise 对象变为拒绝状态,该 Promise 对象的状态也变为拒绝状态,并返回第一个被拒绝的 Promise 对象的拒绝原因。

语法:Promise.all(iterable)

参数:

iterable: 一个可迭代对象,其中每个成员都是 Promise 对象。

返回值:一个 Promise 对象

示例:
 

const promise1= Promise.resolve('hello');

const promise2 = 42;

const promise3 = new Promise((resolve, reject) => {

setTimeout(resolve, 100, 'world');

});

Promise.all([promise1, promise2, promise3]).then((values) => {

console.log(values); // 输出 ["hello", 42, "world"]

});

在上面的示例中,Promise.all() 方法接收一个包含三个 Promise 对象的数组作为参数。promise1 是一个解析为字符串 "hello" 的 Promise 对象,promise2 是一个直接解析为数字 42 的对象,promise3 是一个在 100 毫秒后解析为字符串 "world" 的 Promise 对象。在 then() 方法中,打印出所有 Promise 对象的解析值数组。由于所有的 Promise 对象都已经解析,因此打印出 ["hello", 42, "world"]。

6.2.4 Promise.race()

Promise.race() 方法接收一个由 Promise 对象组成的数组作为参数,并返回一个新的 Promise 对象。当参数数组中的任意一个 Promise 对象变为解决状态或拒绝状态时,该 Promise 对象的状态也会相应地变为解决状态或拒绝状态,并返回解决值或拒绝原因。

语法:Promise.race(iterable)

参数:

iterable: 一个可迭代对象,其中每个成员都是 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"

});

在上面的示例中,Promise.race() 方法接收一个包含两个 Promise 对象的数组作为参数。其中,promise1 在 500 毫秒后解析为字符串 "one",而 promise2 在 100 毫秒后解析为字符串 "two"。由于 promise2 先解析,因此 Promise.race() 方法返回解析为 "two" 的 Promise 对象,并在 then() 方法中打印该字符串。

七.Promise在实际场景中的应用

Promise是一种异步编程解决方案,可以有效地处理异步操作,避免回调地狱,提高代码可读性和可维护性。在实际应用场景中,Promise常用于网络请求、文件读写、定时任务等异步操作。

Promise的原理是基于状态机的概念,包含三种状态:Pending(等待态)、Fulfilled(成功态)和Rejected(失败态)。在Promise对象实例化时,会处于Pending状态,当异步操作完成时,Promise对象的状态会变为Fulfilled或Rejected状态,并返回相应的结果。

以下是一个简单的Promise示例,模拟一个异步获取用户信息的过程:

// Promise示例

function getUserInfo(userId) {

  return new Promise((resolve, reject) => {

    // 模拟异步请求

    setTimeout(() => {

      const users = [

        { id: 1, name: 'Alice', age: 23 },

        { id: 2, name: 'Bob', age: 28 },

        { id: 3, name: 'Charlie', age: 31 }

      ];

      const user = users.find(user => user.id === userId);

      if (user) {

        // 请求成功,将结果通过resolve返回

        resolve(user);

      } else {

        // 请求失败,将错误信息通过reject返回

        reject(new Error('User not found'));

      }

    }, 1000);

  });

}



// 使用Promise获取用户信息

getUserInfo(2)

  .then(user => {

    console.log(user); // { id: 2, name: 'Bob', age: 28 }

  })

  .catch(error => {

    console.error(error); // Error: User not found

  });

上述代码演示了如何使用Promise获取用户信息的过程。在函数getUserInfo内部,首先创建一个新的Promise对象,并在Promise构造函数中定义异步操作的逻辑。这里通过setTimeout模拟异步请求,然后在回调函数中处理异步操作的结果,并根据结果调用resolve或reject方法,将异步操作的结果返回。

在使用Promise获取用户信息时,可以通过调用getUserInfo函数,并使用then方法处理异步操作成功时的结果,或者使用catch方法处理异步操作失败时的错误信息。在这个例子中,使用then方法打印出了获取到的用户信息,使用catch方法捕获了未找到用户时的错误信息。

除了网络请求和文件读写等异步操作外,Promise在定时任务、多个异步操作的协同等场景中也有广泛的应用。通过合理地使用Promise,可以避免回调地狱,提高代码的可读性和可维护性。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值