nodejs中的promise和async以及wait的原理

本文介绍了Promise在JavaScript中的作用,如何通过resolve和reject处理异步结果,以及其在解决回调地狱、生成器和async/await中的应用。重点讲解了Promise链式调用和async/await如何提升代码可读性和简洁性。

promise的作用

  • promise的含义是保证的意思,可以定义一个异步处理的对象
  • 他有两个参数(其实是两个回调函数,因为异步操作就两种结果,ok或者不ok):
    • resolve函数是执行成功时调用的。
    • reject函数是抛出异常时调用的。
  • 于是乎我们一般这么用
    • 定义 Promise对象
var x = new Promise(function(resolve, reject){
	var ret = ....
	if(ret成功){
		return resolve(ret)
	}else{
		return reject(err)
	}
})

	- 对象里面包含处理过程就2个分支: 
	- 如果返回成功,调用resolve函数把Promise实例的状态改为ok,如果失败则调用reject修改状态为失败。
  • 只要new Promise对象,就说明你执行了一个异步操作, x就是Promise对象
    • x这时已经有结果了,要么失败,要么成功; 就可以 x.then方法进行处理了 x.then(success_callback, failed_callback)。

js回调地狱

  • 如果多个连续事件,常规就是不停的callback, 有了Promise,可以then1,then2…进行链式操作, 清晰了不少

生成器和yield

  • 生成器和yield 在python中的用途: 解决了大量数据的遍历,如果都放入list,内存不够用; 如果用生成器, 生成一个值,就yield 返回去处理,处理完了,返回yield上次的位置,继续执行。
  • js中引入生成器和yield,而co模块就是巧妙的用他们控制异步编程: 比如异步操作 yield api1, 等到返回值,再yield api2, 而不用ap1.then( ap2.then )… 一层一层嵌套。
  • co这个词是协程的意思吗?感觉有点那个意思。

async 和wait

  • co模块解决了异步编程的流程控制问题,避免了层层回调
  • es7 准备引入async 和awai来更优雅的异步编程, 实际和co的原理一样,都是借助了Promise实现的。
  • await 后面一般 是Promise对象定义的异步操作
  • await只能在async里面
  • async 定义一个函数,函数里面是一堆await操作,单await 都是从上至下顺序执行的,而整个async函数返回的是一个新的Promise对象, 它相对于整个线程是不会阻塞的。他可能比较耗时
async function A(){}
A() //执行A
console.log("我先执行了哈 hello")

  • 由于A中是一堆异步执行的操作,需要有一些Promise操作,所以只能看到最后一行操作,A中的执行过程一般看不到。
  • async标识后面的函数是异步执行的,不会阻塞主线程的出来。
  • 以上是我百度的,以及 结合自己写puppeeter爬虫,了解到的async和await的操作。欢迎指点错误。

疑问

  • co模块定义的函数,保证了内部是顺序执行的,那么co定义的这个函数如果耗时很久,会阻塞后续的操作吗?
### 使用 `Promise` `async/await` 对数组中的每个元素执行异步操作并返回新数组 在 Node.js 中,可以利用 `Promise.all()` 或者通过 `async/await` 的方式来实现对数组中每个元素的异步处理,并最终返回一个新的数组。以下是两种常见的方法: #### 方法一:使用 `Promise.all()` 当需要并发地对数组中的每一个元素进行异步操作时,可以借助 `Promise.all()` 来完成。 ```javascript function processItem(item) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(item * 2); // 假设我们对每个元素乘以2作为异步操作的结果 }, 1000); }); } async function processArray(array) { const promises = array.map(processItem); // 创建一个由 Promises 组成的数组 const results = await Promise.all(promises); // 并发运行所有的异步操作 return results; } const inputArray = [1, 2, 3]; processArray(inputArray).then(newArray => { console.log(newArray); // 输出: [2, 4, 6] }); ``` 这种方法的优点在于它能够同时启动多个异步任务,从而提高效率[^4]。 --- #### 方法二:使用 `async/await` 配合 `for...of` 循环 如果希望按顺序依次处理数组中的每一项,则可以通过 `async/await` 结合 `for...of` 实现串行化操作。 ```javascript function processItem(item) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(item * 2); // 同样假设这里是对每个元素乘以2的操作 }, 1000); }); } async function processArraySequentially(array) { const newArray = []; for (let item of array) { const processedValue = await processItem(item); // 每次只等待当前一项完成后再继续下一项 newArray.push(processedValue); } return newArray; } const inputArray = [1, 2, 3]; processArraySequentially(inputArray).then(newArray => { console.log(newArray); // 输出: [2, 4, 6], 不过这里的输出会延迟较长时间因为是逐个执行 }); ``` 此方法适用于某些场景下的依赖关系或者资源限制情况,比如数据库连接数有限制等情形[^1]。 --- 上述两段代码展示了如何分别采用 **并发** **串行** 方式去遍历数组并对其中每项应用特定逻辑之后得到新的数据集合。具体选择哪种取决于实际需求以及性能考量因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值