2016-08-02 6 views
4
$(".getDetails").click(function() { 
    // some stuff like fetching response from server 
}) 

ユーザーがUIのgetDetailsボタンを何秒も何度もクリックすると、jqueryはclick関数の呼び出しを2回生成し、ロジックが失敗します。 これは、最初のクリック自体でボタンを無効にすることになると思います(そのため、複数回クリックすることはできません)。一度私は応答を得るか、ちょうどクリック方法から を返す前に私はそれを有効にします。もっと良い解決策はありますか?javascript/jqueryでマルチスレッド問題を処理するには?

いいえ、ユーザーがボタンを最初にクリックするとすぐにボタンを無効にするにはどうすればよいですか。私はclickメソッドを呼び出す前にやっておく必要があると思います。

Javaはsynchronizedキーワードを提供しているので、メソッド内に1つのスレッドしか入っていないので、javascriptに似ているかどうかはわかりませんか?

+0

何ロジックは、クリックハンドラで実行されていますか?私はそれがAJAXの要求だと仮定します –

+0

はいthats正しい – user3198603

+2

はい。連続したクリックを防ぐには、最初のクリック時にボタンを無効にする必要があります。 – James

答えて

2

クリックハンドラがAJAXリクエストを実行すると仮定すると、リクエストを行う前にボタンを無効に設定してから、クエストが完了しました。これを試してみてください:

$(".getDetails").click(function(){} 
    var $btn = $(this).prop('disabled', true); 

    $.ajax({ 
     url: '/foo' 
     success: function() { 
      console.log('It worked!'); 
     }, 
     error: function() { 
      console.log('It failed!'); 
     }, 
     complete: function() { 
      $btn.prop('disabled', false); 
     } 
    }); 
}); 
+0

しかし、この場合も、クリックメソッド内に同時に2つのスレッドが入ってくる可能性があり、その後両方が処理されます。右 ? – user3198603

+0

JSは単なるスレッドであるため、問題は解決しません。しかし、これにより、最初のAJAX要求が完了する前に、イベントハンドラを複数回起動するという、迅速な連続的なクリックの問題を回避できます。 –

+0

申し訳ありませんが、私はあなたがJSがシングルスレッドであることを意味するのですか?最初のスレッドが完了するまで、2番目のスレッドがメソッドに入ることができないことを意味しますか?はいの場合、私は問題に直面してはいけません。ではない ? – user3198603

0

あなたがアンバインドクリックイベントを試してみて、AJAX呼び出した後、再びあなたのロジックを複数回発射を防止するために、単純なフラグを使用することができ、そのクラスに

$(".getDetails").click(function(){} 
$(".getDetails").unbind('click'); 
// some stuff like fetching response from server 
) 
0

をクリックしてバインドすることができます。

var flag = true  
$(".getDetails").click(function() { 

    if (flag) { 
    flag = false; 
    //your logic... 

    //when your code ends (in after-AJAX callback for example) 
    flag = true; 
    } 

}); 
+1

しかし、この場合にも、2つのスレッドが同時に値を取得し、両方が要求を送信する可能性があります。 – user3198603

+2

jsに「2つのスレッド」というものはありません。 –

+0

@ freedomn-m申し訳ありませんが、「2つのスレッド」が「js」のようなものはありません。はいの場合、私は問題に直面してはいけません。 。右 ? – user3198603

0
$(".getDetails").click(function(e){ 

    var $target = $(e.currentTarget); 
    // assuming the click listener is on the button 

    $target.prop('disabled',true); 

    // request, stuff...and when done: 
    $target.prop('disabled',false); 
}) 
0

防ぐデフォルトを試してみて、他のイベントの伝播 を避けるためにはfalseを返す。これは解決策であるセマフォのようなものですか。これはあなたのボタンは非同期に発生しませんことを確認する必要があり

var progress = false; 
$(".getDetails").on('click', function(e) { 
if(!progress){  
progress = true; 
// some stuff like fetching response from server 
//also after sucessfull fetch make true to false again 
}else{ 
    console.log('something in progress'); 
} 
    e.preventDefault(); 
    return false; 

}) 
0

監視応答があるまで2回リクエストしてください。

function doAjaxReq() { 
 
    /* 
 
    Add your ajax operation here 
 
    as a return value of doAjaxReq 
 
    like so: 
 
    
 
    return $.ajax({ 
 
     url: '/foo', 
 
     type: 'POST', 
 
     data: data 
 
    }) 
 
    
 
    Since i can't use ajax here let's smilulate 
 
    it useing a promise. 
 
    */ 
 
    promise = new Promise(function(res, rej) { 
 
    setTimeout(function(){ 
 
     res({foo: "bar"}); 
 
    }, 1000) 
 
    }) 
 
    return promise; 
 
} 
 

 

 
/* 
 
Inside here you add the click handlder 
 
only once use `elem.one('click'...` 
 
*/ 
 
function addClickHandler(elem) { 
 
    elem.one('click', function() { 
 
    // do your ajax request and when its 
 
    // done run `addClickHanlder` again 
 
    // i'm using `.then` because of the promise, 
 
    // you should be using `.done`. 
 
    doAjaxReq().then(function(data) { 
 
     console.log(data); 
 
     addClickHandler(elem); 
 
    }); 
 
    }) 
 
} 
 

 
addClickHandler($(".getDetails"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<button class="getDetails">Get Details</button>