Java教程

JavaScript中 Promise 的理解

本文主要是介绍JavaScript中 Promise 的理解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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的理解

这篇关于JavaScript中 Promise 的理解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!