0

Javascript、webdriverio (v2.1.2) を使用して、内部サイトからデータを抽出しています。だからアイデアは

  • 認証する
  • 認証されたら、必要な URL を開きます
  • 新しいページで、特定のキーワードを持つアンカー タグを検索します
  • 見つかったら、アンカータグをクリックします

以下は私が試したもので、うまくいきます(最後の2点)。それを達成するには、Q と async を使用する必要がありました。私はそれを達成するためにQだけを使用したいと思っていました。Qのみを使用してそれを達成する方法について、誰かが私を助けることができますか??

    var EmployeeAllocationDetails = (function () {
'use stricy';
/*jslint nomen: true */
var Q = require('Q'),
    async = require('async'),   
    _ead_name = 'Employee Allocation Details',
    goToEadFromHome;

goToEadFromHome = function (browserClient) {
    browserClient.pause(500);
    var deferred = Q.defer();
    browserClient.elements('table.rmg td.workListTD div.tab2 div.contentDiv>a', function (err, results) {
        if (err) {
            deferred.reject(new Error('Unable to get EAD page. ' + JSON.stringify(err)));
        } else {

        async.each(results.value, function (oneResult, callback) {
                console.log('Processing: ' + JSON.stringify(oneResult));
                browserClient.elementIdText(oneResult.ELEMENT, function (err, result) {
                    if (err) {
                        if (err.message.indexOf('referenced element is no longer attached to the DOM') > -1 ){
                            callback();
                        } else {
                            callback('Error while processing :' + JSON.stringify(oneResult) + '. ' + err);
                        }
                    } else if(!result){
                        console.log('result undefined. Cannot process: ' + JSON.stringify(oneResult));
                        callback();
                    } else if(result.value.trim() === _ead_name){
                        deferred.resolve(oneResult);
                        callback();
                    }
                });
            }, function (err) {
                // if any of the processing produced an error, err would equal that error
            if( err ) {
        // One of the iterations produced an error.
        // All processing will now stop.
            console.log('A processing failed to process. ' + err);
            } else {
            console.log('All results have been processed successfully');
            }
            }); //end of async.each

        }
    });
    return deferred.promise;
};

return {
    launchEad : goToEadFromHome
  }
})();
module.exports = EmployeeAllocationDetails;

関連する Github の問題リンクhttps://github.com/webdriverio/webdriverio/issues/123

4

1 に答える 1

0

を使うべきだと思いますasync。あなたのコードは素晴らしいと思います。すべてを並行して実行し、エラーを適切に処理します。

もしも

を削除する場合asyncは、いくつかのオプションがあります。

  • Q フロー制御を使用する
  • コピペ async の実装
  • 自分で実装する

Q のフロー制御を使用しようとすると、次のようになります (疑似コード)。

   var getTextActions = [];
   function createAction(element){ 
        return function(){
             return element.getText();
        }
   }

   each(elements, function(element){ getTextActions.push( createAction(element) ) }); 
   Q.all(getTextActions).then(function(results) {
      ... iterate all results and resolve promise with first matching element.. 
   } ); 

この実装はパフォーマンスが悪いことに注意してください。最初にすべての要素からテキストを取得してから、promise を解決しようとします。すべてが並行して実行されるため、実装の方が優れています。

自分で実装することはお勧めしませんが、それでも実装したい場合は、次のようになります (疑似コード):

var elementsCount = elements.length; 
elements.each(function(element){
   element.getText(function(err, result){
      elementsCount --;
      if ( !!err ) { logger.error(err); /** async handles this much better **/  } 
      if ( isThisTheElement(result) ) { deferred.resolve(result); }
      if ( elementsCount == 0 ){ // in case we ran through all elements and didn't find any
            deferred.resolve(null); // since deferred is resolved only once, calling this again if we found the item will have no effect
      }
   })
})

何か不明な点がある場合、またはその場に当てはまらなかった場合はお知らせください。回答を改善します。

于 2014-12-13T15:16:51.647 に答える