JavaScript回调嵌套实现:如何在getName执行后调用getDetails
getDetails的问题 嘿,刚从Python转JavaScript的话,this的指向问题确实是最容易踩的坑之一!我来帮你搞定这个回调嵌套的问题~
首先,你的代码之所以无法正常运行,核心问题是回调函数内部的this和外部的this指向不一样。在JavaScript里,普通函数作为回调执行时,this的指向会发生改变(非严格模式下默认指向window,严格模式下是undefined),所以你在回调里写this.getDetails()的时候,这个this已经不是原来拥有getName和getDetails的那个对象了,自然找不到getDetails方法。
另外,你给回调函数加的getDetails参数其实是多余的,这个参数会接收getName调用回调时传入的参数,但你的getName里只是调用了callback(),没有传任何值,所以这个参数没用,还容易造成混淆,直接去掉就好。
下面给你几种可行的解决方案:
方案1:提前保存外部的this到变量
这是最经典的处理方式,把外部的this存到一个变量(比如self或者that)里,然后在回调函数里用这个变量来访问原对象的方法:
// 先把外部的this存起来 const self = this; this.getName(function() { alert("Done"); // 用self代替this,就能正确访问到getDetails了 self.getDetails(); });
方案2:使用箭头函数
箭头函数的特性就是不会绑定自己的this,而是继承外部作用域的this,这样写起来更简洁:
this.getName(() => { alert("Done"); // 这里的this和外部的this是同一个对象 this.getDetails(); });
方案3:用bind绑定this
可以通过bind()方法把回调函数的this强制绑定到外部的this上:
this.getName(function() { alert("Done"); this.getDetails(); }.bind(this)); // 把回调的this绑定到外部的this
这三种方法都能解决你的问题,其中箭头函数是ES6之后最推荐的写法,代码更简洁直观。
另外补充一点:如果你的getDetails本身也是异步操作(比如需要发起请求),后续如果还要在getDetails完成后执行其他逻辑,那就要把getDetails也改成支持回调的形式,比如:
this.getDetails = function(callback) { // 做异步操作 setTimeout(() => { console.log("getDetails完成"); // 操作完成后调用回调 callback && callback(); }, 1000); };
然后在getName的回调里这样用:
this.getName(() => { alert("Done"); this.getDetails(() => { alert("getDetails也完成了"); }); });
不过目前你的getDetails是同步的,所以前面的三种方案就足够啦~
内容的提问来源于stack exchange,提问作者Nicholas

