调用Promise.all抛非对象错误及Express res.json同类问题咨询
这个问题的核心都是函数调用时的this上下文绑定丢失导致的,咱们逐个场景拆解:
场景1:Promise.all的调用问题
先看你的代码:
updateVideos() .then(videos => { return videos.map(video => updateUrl({ id: video, url: "http://..." })) }) .then(Promise.all) // 抛出Promise.all called on non-object错误
错误原因
Promise.all是Promise构造函数的静态方法,它内部的实现依赖this指向Promise类本身。当你把Promise.all直接传给.then()作为回调时,.then()调用这个函数的方式是「普通函数调用」,此时this的绑定会丢失:
- 在非严格模式下,
this会指向全局对象(比如浏览器的window) - 在严格模式下,
this会变成undefined
不管哪种情况,this都不再是Promise类,所以Promise.all内部检测到this不是预期的对象,就抛出了Promise.all called on non-object的错误。
为什么箭头函数包裹就正常?
当你写成.then(promises => Promise.all(promises))时,是直接通过Promise.all()的方式调用,此时this会通过「隐式绑定」指向Promise类,完全符合方法的预期,所以能正常运行。
场景2:Express res.json的调用问题
再看第二个例子:
promise().then(res.json) // 出现Cannot read property 'app' of undefined错误 promise().then(results => res.json(results)) // 正常运行
错误原因
res.json是Express响应对象res上的实例方法,它内部需要访问res上的属性(比如this.app、this.statusCode等),这依赖this指向res对象本身。
当你直接把res.json传给.then()时,同样丢失了this绑定:.then()调用它时,this不再指向res,而是变成全局对象或undefined,所以内部访问this.app就会抛出Cannot read property 'app' of undefined的错误。
为什么箭头函数包裹就正常?
用箭头函数results => res.json(results)包裹时,我们是通过res.json()的方式调用方法,此时this通过「隐式绑定」指向res对象,方法内部能正常访问所需的属性,所以可以正常运行。
两种场景的共性
这两个问题的本质完全一致:
- 当你把依赖特定
this上下文的函数(比如类的静态方法、对象的实例方法)直接作为回调传递时,函数会脱离原本的上下文,导致调用时this绑定丢失 - 而用箭头函数(或者普通函数)包裹后,我们手动在正确的上下文中调用该方法,保证了
this的正确绑定,从而避免了错误
内容的提问来源于stack exchange,提问作者Faizuddin Mohammed

