Node.js代码放在函数内外执行结果存在差异是什么原因?
核心原因
这是Node.js的异步I/O执行逻辑,加上REPL运行环境的特性,共同导致了你观察到的差异:
https.get是典型的异步非阻塞API:调用后Node.js不会等待网络请求完成、回调执行,会直接继续运行后续的同步代码。你两段代码中写的res.on('data')、res.on('end')回调,都要等网络请求的对应事件触发才会执行,执行时机远晚于后面的console.log和函数return操作。- 封装成函数的版本返回空是必然结果:函数执行到
return chunks[0]时,网络请求还没完成,data事件一次都未触发,chunks还是空数组,自然返回undefined。而且函数内的chunks是局部变量,就算后续回调执行往里面填充了数据,你在函数外部也无法访问这个局部变量。 - REPL中直接运行的版本能拿到值,是因为
chunks被定义成了全局变量:刚执行完代码时,console.log(chunks[0])实际也会输出undefined,等几秒网络请求完成后,回调会往全局的chunks数组里塞数据,你后续在REPL里直接访问chunks[0]时就能拿到已经填充好的内容,给你造成了“第一段代码运行时就能拿到值”的错觉。
额外的代码问题
你的代码中还有一处无效操作:chunks.join()调用后没有赋值给变量,它本身不会修改原数组,只会返回拼接后的字符串,就算等回调执行完,chunks依然是存储分片的数组,不是完整的字符串。
正确的实现方式
用Promise封装异步请求,配合async/await获取结果:
const https = require('https') function readURI(uri) { return new Promise((resolve, reject) => { const chunks = [] https.get(uri, res => { res.setEncoding('utf8') res.on('data', chunk => chunks.push(chunk)) res.on('end', () => resolve(chunks.join(''))) res.on('error', reject) }).on('error', reject) }) } // 调用方式 (async () => { const content = await readURI('https://www.example.com') console.log(content) })()
内容的提问来源于stack exchange,提问作者stanekam
相关产品推荐
相关产品推荐

