彻底理解Nodejs中callback、promise、yield、async、await

callback是Nodejs里最经典写法

const fs = require('fs')
const fileName = 'hello.md'

function fsReadFile (file, cb) {    
	fs.readFile(file, 'utf8', function(err, data) {        
		if (err == null) {            
			// console.log(data)            
			// return data            
			cb(true)        
		} else {            
			// return err            
			console.log(err)            
			cb(false)        
		}
		
	})
}

因为readFile就异步函数,所以想在function里return的都是徒劳。必须用cb(callback的简写)来接收回调,但是这样会引入一个经典的问题,就是回调地狱。

伟大的人类发明了链式调用(promise)来解决它,那么callback怎样转成promise呢?
有两种方法:

方法1、利用new Promise来构建

function promiseReadFile1 (file) {    
	return new Promise((resolve, reject) => {        
		fsReadFile(file, cb => {            
			if (cb) {                
				resolve(cb)            
			} else {                
				reject()            
			}        
		})    
	})
}

再通过以下方法调用就可以

promiseReadFile1(fileName)
.then(r => {    
	console.log(r)
})
.catch(e => {    
	console.log(e)
})

方法2、利用util所带的promisify来构建

const { promisify } = require('util')

const promiseReadFile2 = promisify(fs.readFile)
promiseReadFile2(fileName, 'utf8')  
	.then(result => console.log(result))  
	.catch(err => console.log(err))

有没有更直观些的方法呢?伟大的人类又发明了yield

function* fsReadFileYield(file) {    
	yield promiseReadFile1(file)
}

调用方法1

const v = fsReadFileYield(fileName).next().value
v.then(r => {
	console.log(r)
})

调用方法2
这里yield前要加上return,要不链式调用时then中没有值返回

const co = require('co')
function* fsReadFileYield(file) {    
	return yield promiseReadFile1(file)
}

co(fsReadFileYield(fileName)).then(function (r) {    
	console.log(r)
}).catch(function (err) {    
	console.log(err)
})

或者

#串行调用
function fsReadFileYieldPlus(file) { 
	co(function* () { 
		const prfRet = yield promiseReadFile1 (file) 
		console.log(prfRet) 
		const prfRet1 = yield promiseReadFile1 (file) 
		console.log(prfRet1) 
	}) 
}

fsReadFileYieldPlus(fileName)
	

那还有没有更简便的方法?async和await这对好基友诞生了


async function asyncFsReadFile (file) {    
	const rets = await promiseReadFile1(file)    
	console.log(rets)    
	return rets
}

asyncFsReadFile(fileName)

如果你想直接打印return的值,如以下写法

const r = asyncFsReadFile(fileName)
console.log(r)

你会得到一个

Promise {<pending>}

可以这样玩

async function fn2 (file) {    
	const rets = await asyncFsReadFile(file)    
	console.log(rets)
}
fn2(fileName)

记住有await的地方必须有async,但是有async的地方不一定有await,因为async是一个强大的npm包,可以做流程控制,如串行、并行或两者混合的流程控制。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lcwai

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值