JavaScript 使用Async 和 Promise 完美解决回调地狱

Posted のんきネコ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 使用Async 和 Promise 完美解决回调地狱相关的知识,希望对你有一定的参考价值。

很久以前就学习过Async和Promise,但总是一知半解的。

今天在写NodeJS的时候,发现好多第三方库使用回调,这样在实际操作中会出现多重回调,这就是传说中的JS回调地狱。

举个例子

有一个方法调用redis,访问一个Hash对象表,获取到返回值后,将返回值插入到redis的另外一个Hash对象表中。

testCallbackAction(){
	let redis = RedisClient();

	let key = ‘xx‘;
	redis.hget(redisTable1,key, (err,data)=>{
		err&&think.logger.error(err);

		redis.hset(redisTable2,key,data,(err,data)=>{
			console.log(err);
			console.log(data);
		});
	})
}

 

在上面这个方法中,可以看见它嵌套了2个回调函数。随着业务的复杂,必然导致回调函数的无限嵌套。

这时候就可以使用Async和Promise来解决这个问题。

首先要了解一个Promise和Async的概念。

 

Promise可以看作是一个异步容器。它可以将一个异步调用方法放到一个容器中,在异步处理时,不会直接跳到下一步,而是阻塞,直到异步处理结束并返回一个resolve()方法。

而Ansyc、await 是Promise天生一对的搭档。

在执行Promise时,使用Ansyc将Promise指定为异步方法,然后使用await等待Promise返回resolve方法。

 

 通过这个方式,我们可以对上面的代码进行简化,具体如下:

async testCallbackAction(){
	let redis = RedisClient();

	let key = ‘xx‘;
	let rt = null;
	await new Promise((resolve, reject)=>{
		redis.hget(redisTable1,key, (err,data)=>{
			err&&think.logger.error(err);
			rt = data;
			resolve();
		})
	})

	await new Promise((resolve, reject)=>{
		redis.hset(redisTable2,key,rt,(err)=>{
			console.log(err);
			resolve();
		});
	})
}

  

 通过上面这个方法,可以将回调函数拆开,依次等待回调结束后再执行下一步,而不用将回调嵌套,大大提高了代码的可阅读性。

 

以上是关于JavaScript 使用Async 和 Promise 完美解决回调地狱的主要内容,如果未能解决你的问题,请参考以下文章

在 Firebase Cloud Functions 中使用 async/await 时返回一个 Promise

JavaScript中async和await的使用以及队列问题

JavaScript的异步async和await

使用async属性异步加载执行JavaScript

使用async属性异步加载执行JavaScript

使用 Javascript(以及 Node.js)使用 async/await 和 Promises 的正确方法是啥 [重复]