彻底弄懂Promise!!!

这篇具有很好参考价值的文章主要介绍了彻底弄懂Promise!!!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、什么是Promise

二、为什么使用Promise

三、Promise的基本用法

四、Promise.resolve()与Promise.reject()

五、Promise.then与Promise.catch

六、Promise.all(iterable)与Promise.race(iterable)

七、使用场景

补充


一、什么是Promise

Promise是一种用于处理异步操作的JavaScript对象。它代表了一个尚未完成但最终会完成的操作,并可以返回操作的结果或错误信息。Promise对象有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。当操作完成时,Promise对象可以从pending状态转变为fulfilled状态,表示操作成功完成;或者从pending状态转变为rejected状态,表示操作失败。

二、为什么使用Promise

使用Promise可以更好地处理异步操作,避免了回调地狱(callback hell)的问题。通过使用Promise,可以将异步操作的结果以更直观、可读性更高的方式进行处理,而不需要嵌套多层回调函数。

说到的地狱回调又是什么呢?用一个例子来看看吧。

// 假设有三个异步操作:operation1、operation2、operation3
//地狱回调就是这样子~
operation1(function(result1) {
    operation2(result1, function(result2) {
        operation3(result2, function(result3) {
            // 处理最终结果
        });
    });
});
//使用Promise写法:
operation1()
  .then(result1 => {
    // 在第一个操作完成后执行第二个操作
    return operation2(result1);
  })
  .then(result2 => {
    // 在第二个操作完成后执行第三个操作
    return operation3(result2);
  })
  .then(result3 => {
    // 所有操作完成后的处理
    console.log(result3);
  })
  .catch(error => {
    // 错误处理
    console.error(error);
  });
//你觉得哪一种写法的可读性更好?后期更好维护呢?

三、Promise的基本用法

Promise通过new Promise()将构造函数实例化,Promise构造函数接收一个函数作为参数,这个函数有两个参数resolve,reject,这两个参数也是方法,成功调用resolve(),失败调用reject(),实例创建完成后,可以使用then方法指定成功或者失败的回调函数,也可以用catch捕获失败,then和catch最后也是返回promise对象,所以可以链式调用。

以下是一个使用Promise的简单示例:

const promise = new Promise((resolve, reject) => {
  // 模拟异步操作
  setTimeout(() => {
    const randomNumber = Math.random();
    if (randomNumber > 0.5) {
      resolve(randomNumber);
    } else {
      reject(new Error('Random number is less than 0.5'));
    }
  }, 1000);
});

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

在上面的示例中,我们创建了一个Promise对象,模拟了一个异步操作。如果生成的随机数大于0.5,Promise对象的状态会变为resolved,然后调用promise.then中的回调函数;如果生成的随机数小于等于0.5,Promise对象的状态会变为rejected,然后调用promise.catch中的回调函数。

四、Promise.resolve()与Promise.reject()

Promise.resolve()方法用于将现有对象转为Promise对象。它有四种参数情况:

1. 参数是一个Promise实例

//参数是一个Promise实例,resolve()将不做任何修改,直接返回这个实例。
let p = new Promise((resolve, reject) => {
  resolve('foo');
});
let p1 = Promise.resolve(p);
p1.then(function(value) {
  console.log(value); // 输出:foo
});

2. 参数是一个thenable对象(具有then方法的对象):

let thenable = {
  then: function(resolve, reject) {
    resolve(42);
  }
};
let p2 = Promise.resolve(thenable);
p2.then(function(value) {
  console.log(value); // 输出:42
});

3. 参数是一个原始值或普通对象

let p3 = Promise.resolve('bar');
p3.then(function(value) {
  console.log(value); // 输出:bar
});
let p4 = Promise.resolve({ name: 'Alice' });
p4.then(function(value) {
  console.log(value); // 输出:{ name: 'Alice' }
});

4. 参数没有任何值

let p5 = Promise.resolve();
p5.then(function() {
  console.log('resolved');
});

Promise.reject()方法返回一个带有拒绝原因的Promise对象。它可以用于在Promise链中显式地拒绝一个Promise,并将拒绝原因传递给后续的catch()方法进行处理。

Promise.reject(new Error("BOOM!")).catch(error => { console.error(error); })
 // 输出:Error: BOOM!

上述例子创建了一个被拒绝的Promise对象,并传递了一个Error对象作为拒绝原因。然后使用catch()方法来捕获并处理拒绝的Promise,

五、Promise.then与Promise.catch

Promise.then()方法接受两个参数,分别是onFulfilled和onRejected。这两个参数都是函数,用于处理Promise对象的状态变为fulfilled(已完成)或rejected(已拒绝)时的回调函数。

onFulfilled是当Promise对象的状态变为fulfilled时调用的函数。它接收Promise对象的解决值作为参数,并返回一个新的Promise对象或一个值。如果返回一个新的Promise对象,则后续的then()方法将等待该Promise对象的状态变为fulfilled或rejected,并将其解决值传递给下一个then()方法。如果返回一个值,则后续的then()方法将立即被调用,并将该值作为解决值传递给下一个then()方法。

onRejected是当Promise对象的状态变为rejected时调用的函数。它接收Promise对象的拒绝原作为参数,并返回一个新的Promise对象或一个值。如果返回一个新的Promise对象,则后续的then()方法将等待该Promise对象的状态变为fulfilled或rejected,并将其解决值或拒绝原因传递给下一个then()方法。如果返回一个值,则后续的then()方法将立即被调用,并将该值作为解决值传递给下一个then()方法。

promise.then((value) => {
  // 处理解决值
}, (reason) => {
  // 处理拒绝原因
}).catch((error) => {
  // 处理错误
});

与catch()方法相比,第二个参数onRejected和catch()方法的区别在于,onRejected只会处理当前Promise对象的拒绝原因,而catch()方法可以处理当前Promise对象及其后续Promise对象的拒绝原因。此外,catch()方法还可以在链式调用中更方便地捕获错误。

Promise.then(null,onOejected)用于指定当Promise对象的状态变为rejected时的回调函数。第一个参数为null,表示不处理Promise对象状态变为fulfilled的情况,第二个参数为一个回调函数,用于处理Promise对象状态变为rejected的情况。

let promise = new Promise((resolve, reject) => {
  // 模拟异步操作
  setTimeout(() => {
    reject('Error occurred');
  }, 2000);
});
promise.then(null, (error) => {
  console.log(error); // 输出:Error occurred
});
// .catch()是.then(null, 参数)的别名,结果都是一样的
promise .catch(reason => {
  console.log(reason); // 输出:Error occurred
});
/*这个例子表示promise对象的状态在2秒后变为rejected,并且传递了一个错误信息。
then方法的第一个参数为null,表示不处理状态变为fulfilled的情况,
第二个参数为一个回调函数,用于处理状态变为rejected的情况。*/

同理当promise.then()只有一个参数时,用于处理promise对象的成功状态。

六、Promise.all(iterable)与Promise.race(iterable)

两个方法的区别:

promise.all(iterable):iterable是由多个promise实例组成的可迭代对象(如Array, Map, Set),即将多个 Promise 对象包装成一个新的 Promise 实例。

当iterable中的promise实例都完成,所有实例都变为 fulfilled 状态时,该新的 Promise 实例才会变为 fulfilled 状态,返回所有成功的结果组成的数组当任意一个 Promise 对象变为 rejected 状态时,该新的 Promise 实例就会变为 rejected 状态。只要有一个回调执行失败,then是不会执行的,则在catch中回调第一个失败的结果。

下面是 Promise.all 方法的用法和示例:

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 1 resolved');
  }, 2000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 2 resolved');
  }, 3000);
});
const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('Promise 3 rejected');
  }, 4000);
});
Promise.all([promise1, promise2, promise3])
  .then((values) => {
    console.log(values); // 输出:['Promise 1 resolved', 'Promise 2 resolved']
  })
  .catch((error) => {
    console.log(error); // 输出:'Promise 3 rejected'
  });

在上面的示例中,我们创建了三个 Promise 对象,分别是 promise1、promise2 和 promise3。promise1 和 promise2 分别在 2 秒和 3 秒后变为 fulfilled 状态,而 promise3 在 4 秒后变为 rejected 状态。

然后,我们使用 Promise.all 方法将这三个 Promise 对象包装成一个新的 Promise 实例,并通过 then 方法和 catch 方法分别处理 fulfilled 状态和 rejected 状态。

在 then 方法中,我们可以获取到所有 Promise 对象的结果值,以数组的形式返回。在 catch 方法中,我们可以获取到第一个变为 rejected 状态的 Promise 对象的错误信息。

promise.race(iterable):Promise.race(iterable)方法也接收一个可迭代对象作为参数,返回一个新的Promise对象。只要iterable中的任意一个promise实例resolved或者rejected,返回的promise就会resolved或者rejected。

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 、asyn/await同时返回两个数据给前端。

// 获取产品类别和总价
exports.getCategoryAndNumber = (req, res) => {
	// 获取产品类别数组
	const CategoryArr = () => {
		return new Promise(resolve => {
			const sql = 'select set_value from setting where set_name = "产品设置"'
			db.query(sql, (err, result) => {
				let str = result[0].set_value
				// eval() JSON格式字符串转化为 JSON对象
				const arr = eval('(' + str + ')')
				resolve(arr)
			})
		})
	}
	// 获取价格
	const getNumber = product_category => {
		return new Promise(resolve => {
			const sql = 'select product_all_price from product where product_category= ?'
			db.query(sql,product_category,(err,result)=>{
				let total = 0
				for(let i =0;i<result.length;i++){
					total += result[i]['product_all_price']
				}
				resolve(total)
			})
		})
	}
	// 通过循环类别数组里面每一个类别获取对应的价格
	async function getAll(){
		const category= await CategoryArr()	 
		const price = []
		for(let i =0 ;i <category.length;i++){
			price[i] = await getNumber(category[i])
		}
		res.send({
			category:category,
			price:price
		})
	}
	getAll()
}

补充

  1. Promise.finally():用于指定Promise对象的回调函数,无论Promise对象的状态是成功还是失败,该回调函数都会执行。

  2. Promise.allSettled():接收一个Promise对象的数组作为参数,当这个数组中的所有Promise对象都变为fulfilled或rejected状态时,allSettled()返回一个新的Promise对象。

  3. Promise.any():接收一个Promise对象的数组作为参数,当这个数组中的任意一个Promise对象变为resolved状态时,any()返回一个新的Promise对象。文章来源地址https://www.toymoban.com/news/detail-784400.html

到了这里,关于彻底弄懂Promise!!!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ES6---Promise对象

    前端的一个必学知识之一,Promise对象,是一种用来解决异步编程的方案 特点: 1.对象的状态不受外界影响。 Promise对象代表一个异步操作,有三种状态: pending(进行中)、 fulfilled(已成功)和 rejected(已失败)。 只有异步操作的结果,可以决定当前是哪一种状态,任何其

    2024年02月08日
    浏览(26)
  • ES6 Promise 详解

    目录 一、Promise基本介绍 二、Promise实现多次请求         1.传统Ajax方式实现多次请求 :              1.1 json数据准备             1.2 JQuery操作Ajax         2.使用ES6新特性Promise方式 :  三、Promise代码重排优化         1.问题分析 :          2.代码优化 :              2

    2024年02月08日
    浏览(26)
  • 【ES6知识】Promise 对象

    1.1 概述 Promise 对象用于表示一个异步操作的最终完成(或失败)及其结果值。是异步编程的一种解决方案(可以解决回调地狱问题)。 一个 Promise 对象代表一个在这个 promise 被创建出来时不一定已知值的代理。它让你能够把异步操作最终的成功返回值或者失败原因和相应的

    2024年02月07日
    浏览(30)
  • 【ES6】Promise.all用法

    Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。 上面代码中,Promise.all()方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()方法的参数可以

    2024年02月09日
    浏览(27)
  • 第一章前端开发ES6基础

    认识ES6 概述 ES6表示ECMAScript规范的第六版,正式名称为 ECMAScript 2015 ,ECMAScript是由ECMA国际标准组织制定的一项 脚本语言 的标准规范化,引入了许多新特性和语法。 其中包括 箭头函数、let和const声明、类、模板字符串、解构赋值、参数默认值、展开操作符、Promise 等等。这些

    2024年02月08日
    浏览(36)
  • 第二章前端开发ES6基础

    目录 扩展运算符 概述 语法 应用 模板字符串 概述 应用 内置对象扩展 概述 数组扩展方法 字符串扩展方法 set数据结构 概述 基本使用 操作方法 遍历方法 认识symbol 概述 作用 基本使用 项目 扩展运算符 概述 扩展运算符(spread operator)是 ES6 中新增的一种运算符,用 三个点(

    2024年02月07日
    浏览(35)
  • 【ES6】fetch函数和Promise

    fetch函数是现代JavaScript中用于发起HTTP请求的一个非常强大的工具。它返回一个Promise,这个Promise在请求成功时解析为Response对象,或者在请求失败时拒绝。 以下是一个基本的fetch使用示例: 在这个例子中,我们首先向https://api.example.com/data发起一个GET请求。然后,我们检查响应

    2024年02月09日
    浏览(26)
  • 【ES6】Promise.allSettled的用法

    Promise.allSettled() 是一个Promise方法,用于处理一个Promise数组,返回一个新的Promise数组,每个元素对应原始Promise的状态。这个方法可以用于处理多个异步操作,并且能够获取每个操作的结果和状态。 下面是Promise.allSettled()的详细代码示例: 输出结果: 在上面的代码中,我们创

    2024年02月10日
    浏览(31)
  • 【ES6】Promise.race的用法

    Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。 上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。 Promise.race()方法的参数与Promise.all()方法一样,如果不是 Pr

    2024年02月10日
    浏览(26)
  • ES6基础知识六:你是怎么理解ES6中 Promise的?使用场景?

    一、介绍 Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大 在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码 阅读上面代码,是不是很难受,上述形成了经典的回调地狱 现在通过Promise的改写上面的

    2024年02月15日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包