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);
但是这…不还是进入了异步执行的逻辑么
所以最终结论是同步代码只能通过回调函数,实现同步异步逻辑交替执行的结果
最后如果确定异步逻辑获得了数据,如何强行取出?