ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaScript中 Promise 的理解

2022-04-06 16:02:14  阅读:235  来源: 互联网

标签:function 状态 resolve JavaScript 实例 Promise reject 理解


Promise 是什么?

PromiseES6 提供的一种异步编程解决方案,解决了传统异步处理的回调金字塔问题; Promise 对象是一个构造函数,用来生成 Promise 实例;
Promise 构成:console.dir(Promise);

image

可以看出,Promise 这个构造函数自己身上有 resolve(), reject(), all(), race() 这几种常见的方法,原型上有 catch(), then(), finally() 常用的方法,所以 Promise 的实例可以使用 catch(), then() 等方法;

Promise 的用法

  1. Promise 构造函数接收一个函数作为参数,这个函数有两个参数,这两个参数都是函数,由 js引擎提供;
    // 传递一个函数作为实例化参数
    const promise = new Promise(function(resolve, reject) {
    	if (/* 异步操作成功 */) {
            // 改变状态为 fulfilled
    		resolve(value);
    	} else {
            // 改变状态为 rejected
    		reject(error);
    	}
    });
    
  2. resolve 函数的作用是将 Promise 对象的状态从 "待定"(pending) 改变为 "成功"(fulfilled), 在异步操作成功的时候调用,并将异步操作的结果作为参数传递出去;
    reject 函数的作用是将 Promise 对象的状态从 "待定"(pending) 改变为 "失败"(rejected), 在异步失败的的时候调用,并将异步操作报的错误作为参数传递出去;
  3. 可以使用 Promise 生成的实例 promise 调用 then() 分别指定 fulfilled状态rejected状态 的回调方法;
    /**
     * promise 实例的then方法,接收两个参数,这两个参数都是函数
     * 第一个参数:Promise对象的状态变为 resolved 状态时调用
     * 第二个参数(可选的):Promise对象的状态变为 rejected 状态时调用
    */
    promise.then(function(value) {
    	// value 为 Promise 对象实例化时调用resolve(...)方法传入的值
    	// success code
    }, function(error) {
    	// error 为 Promise 对象实例化时调用reject(...)方法传入的错误
    	// failure code
    });
    

Promise 链式写法

const promise = new Promise(function(resolve, reject) {
	// 获取一个10 以内的正整数
	const num = Math.floor(Math.random()*10);
	if (num > 5) {
		resolve("num 大于 5");
	} else {
		reject("num 小于 5")
	}
});

// 第一个 then
promise.then(function(value) {
	// 状态由 pending 变为 fulfilled 的回调
	// 这里 value 的值为 (num 大于 5)
	return "成功了";
}, function(error) {
	// 状态由 pending 变为 rejected 的回调
	// 这里 error 的值为 (num 小于 5)
})
// 第二个 then
.then(function(value) {
	// 这里 value 的值为 上一个 fulfilled 状态回调的返回值(成功了)
	console.log(value);  // 如果 num > 5 打印 成功了
});

实例化一个 Promise,参数为一个函数,函数体实现随机生成一个10以内的正整数,如果 num > 5Promise 状态改为 fulfilled 状态,并向下传递了一个 "num 大于 5"的字符串,反之,将 Promise 状态改为 rejected 状态,向下传递了一个 "num 小于 5"的字符串;
当第一个 promise 的成功回调里返回 "成功了" 时,第二个 promise 的成功回调的参数就是 "成功了";

由此可以看出,第一个 promise 不管成功回调还是失败回调,他的返回值作为第二个 promise 中的成功时回调函数的参数值;

链式写法能一直then下去的原因:链式调用靠的是返回新的 promise,来保证可以一直走成功或失败;

Promise.resovle

返回一个 Promise 实例,这个实例处于 resolve 状态
根据传入的参数不同有不同返回值:

  1. 值(对象, 数组, 字符串等):作为 resolve 传递出去的值;
  2. Promise 实例:原封不动返回;
// 返回一个立刻成功的promise
// 别人提供 给你一个方法,需要你传入一个promise,但你只有一个普通的值,
// 你就可以通过这个方法把这个普通的值(string number object)转成一个promise对象
Promise.resolve = function(value){
	return new Promise(function(resolve){
		resolve(value);
	});
}

Promise.reject

返回一个 Promise 实例,这个实例处于 reject 状态。
参数一般就是抛出的错误信息;

//返回一个立刻失败的promise
Promise.reject = function(reason){
	return new Promise(function(resolve,reject){
		reject(reason);
	});
}

Promise.catch

Promise.prototype.catch 方法是 .then(null, rejection) 的别名,用于指定发生错误时的回调函数;

//catch原理就是只传失败的回调
Promise.prototype.catch = function(onRejected){
	this.then(null,onRejected);
}

Promise.all

参数:接受一个数组,数组内都是Promise实例
返回值:返回一个 Promise 实例,这个 Promise 实例的状态转移取决于参数的 Promise 实例的状态变化。当参数中所有的实例都处于 resolve 状态时,返回的 Promise 实例会变为 resolve 状态。如果参数中任意一个实例处于 reject 状态,返回的 Promise 实例变为 reject 状态;

Promise.all = function(promises){
	return new Promise(function(resolve,reject){
		let done = gen(promises.length,resolve);
		for(let i=0;i<promises.length;i++){
			promises[i].then(function(data){
				done(i,data);
			},reject);
		}
	});
}

Promise.race

参数:接受一个数组,数组内都是 Promise 实例
返回值:返回一个 Promise 实例,这个 Promise 实例的状态转移取决于参数的 Promise 实例的状态变化。当参数中任何一个实例处于 resolve 状态时,返回的 Promise 实例会变为 resolve 状态。如果参数中任意一个实例处于 reject 状态,返回的 Promise 实例变为 reject 状态;

Promise.race = function(promises){
	return new Promise(function(resolve,reject){
		for(let i=0;i<promises.length;i++){
			promises[i].then(resolve,reject);
		}
	});
}

总结

Promise 对象有三种状态,并且不受外界影响,Promise 的状态一旦改变就不会再变,并且状态不可逆,只能从 pending(待定) 改变成 fulfilled(成功)pending(待定) 改变成 rejected(失败);

  1. pending(待定)
  2. fulfilled(成功)
  3. rejected(失败)

正是因为这些特点导致 Promise 有三个缺点:

  1. 无法取消 Promise,一旦新建就会立即执行,中途无法取消;
  2. 如果没有设置回调函数,Promise 内部抛出的错误,不会反映到外部;
  3. Promise 处于 pending 状态时,无法得知目前进展到哪一个阶段,是刚刚开始还是即将完成;

学习借鉴链接

谈谈我对Promise的理解

标签:function,状态,resolve,JavaScript,实例,Promise,reject,理解
来源: https://www.cnblogs.com/operate/p/16105943.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有