Javascript(NodeJS)如何处理与事件有关的范围和上下文

时间:2016-06-28 17:00:23

标签: javascript node.js javascript-events scope event-handling

我在情境中有点困惑,
给出示例代码,我在这里加载了几个url,并连接了事件Listener

var pages= Array();
var loading= Array();

for(i=0; i < urls.length; i++){
var page =new WebPage(urls[i]);

   page.onLoadStarted = function() {
       loading[i]= true;
       console.log('Loading started');
   };    
   pages[i]=page;

}

我有5个网址,我得到5次&#34;正在加载#34;在控制台输出中,但是加载数组只有一个定义的值(true),其余的都是&#34; undefined&#34 ;; 看起来当事件被触发时loading[i]= true;使用i的最后一个值来访问数组而不是使用其地址。我该如何解决这个问题?

我尝试在页面对象中添加属性,但同样的事情发生了;

这是我尝试过的:

var pages= Array();

for(i=0; i < urls.length; i++){
var page =new WebPage(urls[i]);

   page.onLoadStarted = function() {
       page.loading= true;
       console.log('Loading started');
   };    
   pages[i]=page;

}

2 个答案:

答案 0 :(得分:1)

如果onLoadStarted是一个事件处理程序,那么for循环的执行速度比所有事件处理程序快得多。在那个时间i5,并且在每次函数调用期间,数组的第六个索引都填充了true值。由于数组的较低索引没有任何设置值,因此您可以获得此类输出。

一种选择是使用Array.prototype.forEachArray.prototype.map方法。这两个函数都将函数作为处理程序。作为函数的处理程序创建一个新范围并记住定义的值。

urls.forEach(function(url /* element */, i /* index */) {
   var page = new WebPage(url);

   page.onLoadStarted = function() {
       loading[i]= true;
       console.log('Loading started');
   };    
   pages[i]=page;
}) 

答案 1 :(得分:1)

尝试使用此代码(es6)

    let pages = Array();
    urls.map((url,i) =>{
     let page = new WebPage(urls[i]);

     page.onLoadStarted(() =>{
      loading[i] = true;
      console.log('Loading started');
     })

(ES5)

    var pages = Array();
    urls.map(function(url,i){
     var page = new WebPage(urls[i]);

     page.onLoadStarted(function(){
      loading[i] = true;
      console.log('Loading started');
     })