Node.js中异步IO无法更新对象引用问题求助
解决Node.js异步IO无法更新对象引用的问题
这问题我太熟悉了!核心症结在于异步回调函数里的this指向跑偏了——你在fs.readFile的回调里用的this,根本不是Report类的实例对象,所以不管怎么赋值,都没法更新到你创建的myReport实例的report属性上。
下面给你三种靠谱的解决办法,挑你习惯的用就行:
方法1:用ES6箭头函数(最简洁)
箭头函数不会绑定自己的this,它会继承外层作用域的this——也就是initializeReport方法执行时的this(也就是你的Report实例)。修改后的代码如下:
var fs = require("fs"); var async = require("async"); var myReport; function Report() { this.report = null; } Report.prototype.initializeReport = function(callback) { fs.readFile("./scrape reports/Scrape Report 1522604653782", "utf-8", (err, data) => { this.report = JSON.parse(data); console.log("Found this report: " + this.report); callback(); }); } module.exports = function() { myReport = new Report(); myReport.initializeReport(function() { console.log(myReport.report); // 这里可以正确打印更新后的report了 }); }
方法2:提前保存this的引用(兼容旧版Node.js)
如果你的项目还在使用不支持箭头函数的旧Node.js版本,可以在进入异步回调前,把当前实例的this存到一个变量里(比如self或者that),回调里用这个变量访问实例:
Report.prototype.initializeReport = function(callback) { const self = this; // 把当前实例的this存起来 fs.readFile("./scrape reports/Scrape Report 1522604653782", "utf-8", function(err, data) { self.report = JSON.parse(data); console.log("Found this report: " + self.report); callback(); }); }
方法3:用bind()绑定this
通过Function.prototype.bind()方法,把回调函数的this强制绑定到当前的Report实例上:
Report.prototype.initializeReport = function(callback) { fs.readFile("./scrape reports/Scrape Report 1522604653782", "utf-8", function(err, data) { this.report = JSON.parse(data); console.log("Found this report: " + this.report); callback(); }.bind(this)); // 绑定this到当前实例 }
另外提醒下,你原来代码里的console.log(...);应该是要打印myReport.report吧?修改后执行,就能看到实例的report属性已经被正确更新啦!
内容的提问来源于stack exchange,提问作者colinrob
相关产品推荐
相关产品推荐

