2016-08-17 9 views
0

最初の部分:ストア、複数の

現在、私は、私は、それぞれが完全にリンクにこの部分の作業をこすり落とし開き、リンクを取得するためのWebページを掻き取ります。

第二部:

が(選択)オプションフィールドの選択であり、この部分も正常に動作アレイの値(ID)が記憶されているかどうかの確認。

第三部:

私はそれらをループ(オプションの選択)したいとクリックイベントを発射し、その後infoProductは、配列でそれをSTOR抽出AJAXの応答を待ちます。

this.eachThenが起動する前にreturn listProductsが呼び出されているため、この部分で問題があります。空の配列があります。

function getInfosProduct(obj,variation) { 
    if (!variation) { 
     return [{ 
      name: getName(), 
      image: products.image.getElement.link + getImage(), 
      url: obj.url 
     }]; 
    } else { 
     return { 
      name: getName(), 
      image: products.image.getElement.link + getImage(), 
      url: variation.url, 
      idVariation: variation.id, 
      descVariation: variation.description 
     }; 
    } 
} 

function clickVariation(variation) { 
    if (variation.ok && variation.id != variation.ignore) { 
     chooseVariation(products.selector, variation.id); 
     return true; 
    } 
    return false; 
} 

casper.getInfosProducts = function(obj) { 
    if (obj.level == 0) { 
     return this.evaluate(getInfosProduct, obj,false); 
    } else { 
     listProducts = []; 
     this.eachThen(obj.levelVariation, function getInfosProducts(variation) { 
      isClick = this.evaluate(clickVariation, variation.data) 
      if (isClick) { 

       this.waitForSelectorTextChange('.selector', function() { 
        this.echo('The text on .selector has been changed.'); 
       }); 

       listProducts.push(this.evaluate(getInfosProduct, obj,variation.data)); 
           } 
     }); 
     return listProducts; 
    } 
}; 

select要素

function chooseVariation(selector, valueToMatch) { 
    var select = document.querySelectorAll(selector), 
     found = false; 
    Array.prototype.forEach.call(select, function(opt, i) { 
     if (!found && opt.value.indexOf(valueToMatch) !== -1) { 
      select.selectedIndex = i; 
      found = true; 
     } 
    }); 
    // dispatch change event in case there is some kind of validation 
    var evt = document.createEvent("UIEvents"); // or "HTMLEvents" 
    evt.initUIEvent("change", true, true); 
    select[0].dispatchEvent(evt); 
} 

に変更イベントをトリガする機能は、これが主なfucntionです:

function startSraping(obj) { 
     casper.then(function switchAction() { 
      switch (obj.action) { 

       //......... some code ........ 

      // iterating through array links and open pages 
      case "openLinks": 
       this.each(links, function eachOpenLinks(self, link) { 
        if (link.ok) { 
         self.thenOpen(link.url, function thenOpenLinks() { 
          startSraping({ 
           url: link.url, 
           action: "getVariations" 
          }); 
         }); 
        } 
       }); 
       break; 

        // get all variations for each page opend 
       case "getVariations": 
        objVariations = this.getVariations(obj.url); 
        startSraping({ 
         url: obj.url, 
         action: "getInfosProducts", 
         objVariations: objVariations 
        }); 
        break; 

       case "getInfosProducts": 
        this.eachThen(obj.objVariations.list, function(levelVariation) { 
         infosProd = this.getInfosProducts({ 
          levelVariation: levelVariation.data, 
          url: obj.url, 
          level: obj.objVariations.level 
         }); 
         // Here I got an empty array 
         this.echo(JSON.stringify(infosProd), 'INFO'); 
        }); 
        break; 
      } 
     }); 
    } 
    casper.start(url, function start() { 
     startSraping({ 
      variation: variation, 
      action: "submitSearch" 
     }); 
    }); 
    casper.run(); 

答えて

1

あなたは(非同期関数を呼び出すことはできませんeachThenwaitForSelectorTextChangeは両方とも非同期です)非同期関数からの結果を同期的に返すことになっています(general reference)。 CasperJSは約束をサポートしていないので、少し難解です。

私は以下の変更が最小限で、どこに行きたいかを知っておくべきだと思います。 startSraping

casper.getInfosProducts = function(obj, callback) { 
    if (obj.level == 0) { 
     this.then(function(){ 
      callback.call(this, arr.push(this.evaluate(getInfosProduct, obj,false)); 
     }); 
    } else { 
     var listProducts = []; 
     this.eachThen(obj.levelVariation, function getInfosProducts(variation) { 
      var isClick = this.evaluate(clickVariation, variation.data) 
      if (isClick) { 
       this.waitForSelectorTextChange('.selector', function() { 
        this.echo('The text on .selector has been changed.'); 
        listProducts.push(this.evaluate(getInfosProduct, obj, variation.data)); 
       }); 
      } 
     }); 
     this.then(function(){ 
      callback.call(this, listProducts); 
     }); 
    } 
}; 

case "getInfosProducts": 
    this.eachThen(obj.objVariations.list, function(levelVariation) { 
     this.getInfosProducts({ 
      levelVariation: levelVariation.data, 
      url: obj.url, 
      level: obj.objVariations.level 
     }, function (infosProd){ 
      // this is the asynchronous callback 
      this.echo(JSON.stringify(infosProd), 'INFO'); 
     }); 
    }); 
    break; 
+0

天才答えは、 "私は、それから/ :)、明確かつ完全な答えを待つ同期/非同期についてのあなたの記事を読んで"。私はそれが仕事をしなかった理由を知っていたが、それを解決する方法を知らなかった。しかし、プロセスは 'callback(listProducts)'に達したときに停止しました。 – abdel

+0

残念です。私はコールバックの 'this '値を正しく設定するのを忘れました –

+0

それは完全に動作します、ずっとgracias :)あなたは人生を救います。しかし、私は2つの変更を加えました: 'arr.splice'を覚えました。なぜなら、' wait'の中に日付がNULLなので、 'variation.data'を変数に入れました。 – abdel

関連する問題