简体   繁体   English

然后在该函数中调用promise的内部访问函数参数

[英]Access to fuction argument inside then of promise called in that function

In some class in constructor I have method that is attached to click event listener. 在构造函数的某个类中,我具有附加到click事件监听器的方法。 this.mapButton.addEventListener('click', this.expandOrCollapseMap.bind(this)); The responsibility of that method is to download map and expand it on the view. 该方法的责任是下载地图并在视图上展开它。

expandOrCollapseMap(eventArgs) {
    // eventArgs.currentTarget != null
    loadGoogleMapsApi({
        key: '{{GOOGLE_MAPS.API_KEY}}',
    }).then((googleMaps)=>{
        if(!this.map) {
            this.mapAPI = googleMaps;
            this.map = new googleMaps.Map(this.mapContainer, {
                zoom: 12,
                center: {
                    lat: 40.722216,
                    lng: -73.987501
                },
                scrollwheel: false
            });
        }
    }).then(()=>{
        // eventArgs.currentTarget is null
        let clickedButton = eventArgs.currentTarget;
        this.changeMapIcon(clickedButton);
        this.changeMapHeight();
        this.addMarkersToMap(this.restaurants);
        this.expanded = !this.expanded;
    })
    .catch((err)=>{
        this.map = null;
        console.log("Error while loading map: ", err);
    });
}

My question is why when I debug in Chrome outside promise then I can access eventArgs.currentTarget , while inside then callback eventArgs.currentTarget is null, but other properties of eventArgs can be accessed? 我的问题是,为什么当我在Chrome以外的承诺调试然后我可以访问eventArgs.currentTarget ,而里面则回调eventArgs.currentTarget为空,但其他性质eventArgs可以访问?

The event is shared across all elements it bubbles to. 该事件在它所涉及的所有元素之间共享。 That means every element that shares the event will receive the same instance of the event object. 这意味着共享事件的每个元素都将接收事件对象的相同实例。 Why is it important? 它为什么如此重要?

According to MDN 根据MDN

(event.currentTarget) Identifies the current target for the event, as the event traverses the DOM. (event.currentTarget)标识事件的当前目标,因为事件遍历DOM。 It always refers to the element to which the event handler has been attached, as opposed to event.target which identifies the element on which the event occurred. 它始终引用事件处理程序已附加到的元素,而不是event.target,后者标识发生事件的元素。

Summing up: event.currentTarget is a transient property on the object that is the same for all the event's subscribers; 总结: event.currentTarget是对象上的一个临时属性,对于所有事件的订阅者都相同; that means that after your event listener is finished, the currentTarget will be set to the next event listener's element until there will be none found and currentTarget will be (correctly) set to null. 这意味着您的事件侦听器完成后, currentTarget将被设置为下一个事件侦听器的元素,直到找不到任何元素,并且currentTarget被(正确地)设置为null为止。

See the described example below: 请参见下面描述的示例:

 document.getElementById('btnnnn').addEventListener('click', e => { e.test = 'test'; // we set here the property to prove that event object is shared with body // now we'll print two similar properties that are in fact totally different in all senses console.log('inside event', e.target, e.currentTarget); // and now we delay the same thing; it is going to be executed after all event listeners setTimeout(() => console.log('after all event listeners', e.target, e.currentTarget), 0); }); // check that it's the same object document.body.addEventListener('click', e => console.log('body, same object?', e.test)); 
 <button id="btnnnn">Click me</button> 

And finally here is the specification that at point 7 clearly instructs to set currentTarget to null after event has completed its cycle. 最后是这里的规范 ,在事件完成其周期后,第7点明确指示将currentTarget设置为null。

This is due to event bubbling . 这是由于事件冒泡 The very same event object will be fired on different elements, and will have currentEventTarget set to the current element before the listeners installed on that element are fired. 完全相同的事件对象将在不同的元素上触发,并且在触发在该元素上安装的侦听器之前,将currentEventTarget设置为当前元素。 As soon as the event reaches the document root, the currentEventTarget is set to null . 一旦事件到达文档根目录, currentEventTarget就会设置为null So if you are observing it asynchronously (in the promise callback), that's the value you will get. 因此,如果您异步观察它(在promise回调中),那么您将获得该值。

The workaround is trivial: Just put the let clickedButton = eventArgs.currentTarget; 解决方法很简单:只需let clickedButton = eventArgs.currentTarget; at the top of the function. 在功能的顶部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM