当前位置: 首页 > 工具软件 > node-promise > 使用案例 >

关于nodejs的Promise

秦城
2023-12-01

#nodejs的Promise

##参考

http://es6.ruanyifeng.com/#docs/promise

##说明

  • 笔者环境为Ubuntu16.04、node6.×.×,使用语言版本为ES6

##Promise介绍

  • Promise是nodejs异步编程的一种方式,ES6把Promise写入了语言标准,原生支持了Promise语法

  • Promise包括的类方法有:Promise.resolve()、Promise.reject()、Promise.all()、Promise.race()

  • Promise包括的原型方法有:Promise.prototype.then()、Promise.prototype.catch()

  • prototype代表Promise的原型,nodejs的对象方法、类方法和原型方法的知识点自行查阅资料

  • Promise对象有三种状态,pending、resolved、rejected,其中resolved和rejected都为结束状态,rejected代表抛出异常的状态,会调用then方法中的第二个回调函数,或者被catch方法处理,具体见下文

  • resolve(<参数>)和reject(<参数>)可以改变Promise对象的状态,一旦Promise对象成为其中一种结束状态,Promise的状态便不可被改变了,但是在改变状态之后的代码还是会执行的(这是不应该的,所以建议不要在resolve(<参数>)或reject(<参数>)之后还有操作,最好直接return resolve(<参数>)或return reject(<参数>))

    	new Promise((resolve,reject)=>{
    		resolve('resolve');
    		reject("reject");
    		console.log("aaaaaaaaa");
    	}).then((a)=>{
    		console.log(a);
    	}).catch((err)=>{
    		console.log(err);
    	});
    
    	结果:
    	aaaaaaaaa
    	resolve
    
  • Promise的异常如果不捕获,是不会中断程序的,会被nodejs的unhandledRejection事件监听到并在控制台报出unhandledRejection异常,也就是说如果上层没有异常,而Promise内发生异常,程序依然正常执行并退出,退出码为0

    	new Promise((resolve,reject)=>{
    		reject("reject");
    	}).then((a)=>{
    		console.log(a);
    	});
    
    	结果:
    	UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): reject
    	exited with status 0
    
  • Promise的Promise.resolve()、Promise.reject()和new Promise()的方式并不能实现异步,then和catch的回调函数才是异步的内容

  • 另外,Promise.resolve()、Promise.reject()以及new Promise()返回的Promise对象直接就是对应的状态;而then、catch由于异步,会先返回一个pending状态的对象,直到异步完成改变它的状态;all、race会在把所有数组元素转为Promise后返回一个pending状态的Promise,然后根据数组中的Promise的最终状态确定它的状态

##Promise.resolve

  1. 这个方法有一个参数,返回一个resolved状态的Promise对象
  2. 相当于new Promise((resolve, reject) => resolve(<参数>))
  3. 如果传入的是一个Promise对象,那么什么都不做直接返回该对象
  4. 如果传入的是一个thenable对象(一个具有then方法的对象),那么会先执行then方法然后返回执行then后的Promise对象
  5. 如果不是Promise或者thenable对象(比如字符串),会将参数直接作为后续方法(比如then)的参数
  6. 可以不带参数,这时直接返回一个Promise对象

##Promise.reject

  1. 这个方法有一个参数,返回一个rejected状态的Promise对象,但是有一点特别的是,它的参数不管是什么,都会原封不动的作为后续方法(比如then)的参数
  2. 相当于new Promise((resolve, reject) => reject(<参数>))
  3. 可以不带参数,这时直接返回一个Promise对象

##Promise.all

  1. 这个方法的参数是一个数组,如果数组成员不是Promise对象,就会先调用上面的Promise.resolve方法变成一个Promise再进一步处理

  2. 方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise对象

  3. 返回一个Promise,当数组的所有Promise状态为resolved时,返回的Promise对象状态才是resolved,所有的Promise对象的返回值成为一个数组作为返回的Promise的返回值

    	var a = new Promise((resolve,reject)=>{
    		resolve("resolve1");
    	});
    	var b = new Promise((resolve,reject)=>{
    		resolve("resolve2");
    	});
    	var c = new Promise((resolve,reject)=>{
    		resolve("resolve3");
    	});
    	Promise.all([a,b,c,'22']).then((t)=>{
    		console.log(t[0]);
    		console.log(t[1]);
    		console.log(t[2]);
    		console.log(t[3]);
    	});
    
    	结果:
    	resolve1
    	resolve2
    	resolve3
    	22
    
  4. 如果数组中有一个Promise对象的状态变为rejected,那么返回的Promise状态为rejected,此时第一个被reject的Promise的返回值会成为返回的Promise对象的返回值

    	var a = new Promise((resolve,reject)=>{
    		resolve("resolve1");
    	});
    	var b = new Promise((resolve,reject)=>{
    		reject("reject2");
    	});
    	var c = new Promise((resolve,reject)=>{
    		reject("reject3");
    	});
    	Promise.all([a,b,c,'22']).then((t)=>{
    		console.log(t[0]);
    		console.log(t[1]);
    		console.log(t[2]);
    		console.log(t[3]);
    	},(t)=>{
    		console.log(t);
    	});
    
    	结果:
    	reject2
    

##Promise.race

  1. 这个方法的参数是一个数组,如果数组成员不是Promise对象,就会先调用上面的Promise.resolve方法变成一个Promise再进一步处理

  2. 方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise对象

  3. 返回一个Promise,当数组中有Promise对象改变状态时,返回的Promise对象就会确定了一样的状态,此时的Promise的返回值会成为返回的Promise对象的返回值

    	var a = new Promise((resolve,reject)=>{
    		setTimeout(()=>reject('reject'), 1000);
    	});
    	var b = new Promise((resolve,reject)=>{
    		console.log('111');
    		setTimeout(()=>console.log('222'), 1100);
    		setTimeout(()=>resolve("resolve"), 2000);
    	});
    	Promise.race([a,b]).then((t)=>{
    		console.log(t);
    	},(t)=>{
    		console.log(t);
    	});
    
    	结果:
    	111
    	reject
    	222
    

##Promise.prototype.then

  1. 由两个回调函数作为参数,第一个是Promise的resolved状态的回调,第二个是Promise的rejected状态的回调

  2. 返回的依然还是一个新的Promise对象,未执行回调函数时状态是pending,而执行后,不管是第一个还是第二个回调函数,默认返回的Promise最后是resolved状态,如果要使then方法返回的Promise最后是rejected状态,需要在回调函数里面使用return返回一个最后是rejected状态的Promise对象

  3. 可以采用链式的写法,在then后面再接着then,如果前一个then第一个回调为空,Promise的resolved状态的返回值,会被传递到下一个then;如果前一个then第二个回调为空,Promise的rejected状态的返回值,会被传递到下一个then或者catch;注意,即使回调的参数列表为空那也是有这个回调,返回值就会被处理掉

    	Promise.resolve('resolve').then((result)=>{
    		console.log(result);
    		return Promise.reject('reject');
    	},(result)=>{
    		console.log(result);
    	}).then(()=>{}).then((result)=>{
    		console.log(result);
    	},(result)=>{
    		console.log(result);
    	});
    
    	结果:
    	resolve
    	reject
    

##Promise.prototype.catch

  1. 其实就是.then(null, rejection)的别名,用于捕获rejected状态
  2. 建议使用这个方法,取代then的第二个回调函数,提高代码可读性

##自己给Promise添加原型方法

Promise.prototype.funcName = function(onResolve, onReject) {
	......
}

onResolve和onReject是和then一样的回调参数,可以有也可以没有,至于函数内容自己定义,只要符合nodejs的语法就可以了,用this表示Promise的原型对象

转载于:https://my.oschina.net/u/3628490/blog/1860158

 类似资料: