nodejs从异步事件中获取数据方法

2022年6月2日10:16:19

nodejs对异步的实现非常彻底,接触时间不久,写爬虫的时候按照以往的思路将request的结果直接赋值给全局变量,结果发现没有输出,对此很困惑,经过查询发现如下

看下面的片段,输出为空

fs.readFile是异步读取,log函数输出是getDate()还没有获取到数据

const fs=require('fs')functiongetData(){
	fs.readFile('demo.txt',(err,data)=>{//异步事件return data;})}
console.log(getData())

再看看promise实现,log函数仍旧没有输出,和回调函数的问题一样

const fs=require('fs')functiongetData(){
	fs.promises.readFile("demo.txt").then(function(result){return result}).catch(function(error){ 
   		console.log(error);})}
console.log(getData())

所以,要想获取异步逻辑的数据,就只能等待异步函数执行完毕得到数据之后在获取,需要延迟获得自然想到了回调函数

全局log仍旧无法输出,意味着同步逻辑没有获得异步数据

const fs=require('fs')
data=''functiongetData(callback){
	fs.promises.readFile("demo.txt").then(function(result){return result})}getData(function(result){
	console.log(result)
    data= result})
console.log(data)

再来看看promise

利用回调函数无效

直接返回promise,表明该结果在未来才能获取,仍旧需要在同步代码中进行回调,显而易见回调仍旧无效

async实际上是promise的封装,结果也相同

const fs=require('fs')
data=''functiongetData(callback){
	fs.promises.readFile("demo.txt").then(function(result){callback(result)})}getData(function(result){
	console.log(result)
    data= result})
console.log(data.toString())//返回promise
data=''functiongetData(callback){return fs.promises.readFile("demo.txt").then((data)=>data)}getData().then((res)=>data=res)
console.log(data.toString())//或者asyncasyncfunctiongetData(callback){returnawait fs.promises.readFile("demo.txt")}

或者以订阅发布模式获取,仍旧无效(按理说是可以的)

var events=require('events');var fs=require('fs')var EventEmitter=newevents.EventEmitter();
data=''functiongetData(){
	fs.readFile('demo.txt',(err,data)=>{
		EventEmitter.emit('sendData',data)})}getData()
EventEmitter.on('sendData',function(res){
    data= res})
console.log(data);

以上对nodejs简单的异步代码进行了回顾,可见同步代码和异步代码是两条不同的执行逻辑,之所以同步获取不到异步数据,是由于异步数据的获取时间未知,比起回调函数,强行获取也是不合逻辑的

来看看同步方式就完全没有问题

var fs=require('fs')
data=''functiongetData(){return fs.readFileSync('demo.txt')}
data=getData()
console.log(data.toString())

进一步思考,既然同步代码是因为不确定异步数据的时机,还没有获取到就执行完毕了,那让同步代码等待不就行了?

然而查找发现nodejs并没有sleep函数的实现,但是可以通过setTimeout进行模拟,将同步逻辑包裹起来

setTimeout(()=>{
    data.toString())},3000);

但是这…不还是进入了异步执行的逻辑么

所以最终结论是同步代码只能通过回调函数,实现同步异步逻辑交替执行的结果

最后如果确定异步逻辑获得了数据,如何强行取出?

  • 作者:zhaojiew
  • 原文链接:https://blog.csdn.net/sinat_41567654/article/details/124993139
    更新时间:2022年6月2日10:16:19 ,共 2029 字。