Robert
Robert

Reputation: 2824

stop javascript till jquery trigger finished

i have this code and what i want is that function b to run only after function a is completed. the problem is: function b does not wait until ajax is complete
i tried when -> done and call back and don't work always alert 1 then 3 then 2 so can anyone help me.

note : this is not the real code, it's just sample one of it cause the file is about 500 lines
in the real code this will happen more than one time when the page is loaded for "first time"

index.php

<select id="first_select">
    <option value=''>select one</option>
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
</select>
<select id="second_select">
</select>
<div id="result">test</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
    $(document).ready(function(){
        $("#first_select").change(function(){
            first=$(this).val();
            $.post("test.php",{first:first},function(result){
                $("#second_select").empty();
                $("#second_select").append(result);
                alert(2);
            });
            alert(1);
        });
        $("#second_select").change(function(){
            second=$(this).val();
            $("#result").text(second);
            alert(3);
        });
        function a(callback){
            $("#first_select").val(1);
            $("#first_select").trigger('change');
            callback();
        }
        function b(){
            $("#second_select").val(4);
            $("#second_select").trigger('change');
        }
        /*$.when( a() ).done(function() {
            b();
        });*/
        /*$.when( a() ).then(function() {
            b();
        });*/
        a(function(){ b();});

    });
</script>

test.php

<?php
    echo "<option value=''>select one</option>";
    echo "<option value='",$_POST['first']+3,"'>",$_POST['first']+3,'</option>';
    echo "<option value='",$_POST['first']+4,"'>".$_POST['first']+4,'</option>';
?>

what i want is function b run after trigger done from function a only, so if it is triggered by user it won't run

Upvotes: 0

Views: 119

Answers (3)

frankfg
frankfg

Reputation: 625

If you need to chain tasks each then should return the promise that belongs to the current task, try this:

    $(document).ready(function () {

        var callback = function () {
            console.log(3);
        };

        $("#first_select").change(function () {
            first = $(this).val();
            $.post("/echo/json", {
                first: first
            }).then(function (result) { // alert(2)
                console.log(2);
                $("#second_select").empty();
                /*
                 * Maybe you are missing the following return
                 */
                return $("#second_select").append(result); //then shoud return a promise.
            }).then(function (data) { //alert(3)
                callback();
            });
            console.log(1);
        });

    });

Fiddle Here

Upvotes: 0

SilentTremor
SilentTremor

Reputation: 4902

Use semaphore in js:

//
//Simple counting semaphore used at asinc call to test end execution to R&R and BIN
//
function CountingSemaphores()
{
    this._semaphore = 0;
    this.wait = function ()
    {
        this._semaphore--;
    };
    this.signal = function ()
    {
        this._semaphore++;
    };
    this.green = function ()
    {
        this._semaphore = 0;
    }
    this.cross = function ()
    {
        return (this._semaphore >= 0);
    }
}

use like:

var semaphore = new CountingSemaphores();

Validation:

function wait_for_green()
{
    if (!semaphore.cross())
    return false;
    else
    return true;
}
function start_consumming()
{
  //large processing
  semaphore.signal();
}

function main()
{
    semaphore.wait();
    start_consumming()
    while (wait_for_green())
    {
       //delay something 
     }
    //start processing
}

Upvotes: 0

James
James

Reputation: 4354

I'm a bit confused about what you're trying to achieve, but I think this should do it (whatever it is?!). The only changes I've made is set the callback to a variable and then it is executed if it exists. You'll need to clear this variable then by setting it to null or whatever if you don't want it to execute on future changes (I don't know if you do or not want this.)

$(document).ready(function(){
        var myCallback;
        $("#first_select").change(function(){
            first=$(this).val();
            $.post("test.php",{first:first},function(result){
                $("#second_select").empty();
                $("#second_select").append(result);
                alert(2);
                // Check if there was a callback set that we want to run.
                if(myCallback){
                   myCallback();
                }
            });
            alert(1);
        });

        $("#second_select").change(function(){
            second=$(this).val();
            $("#result").text(second);
            alert(3);
        });

        function a(callback){
            // Set the callback.
            myCallback = callback;
            $("#first_select").val(1);
            $("#first_select").trigger('change');                
        }

        function b(){
            $("#second_select").val(4);
            $("#second_select").trigger('change');
        }

        a(function(){ b();});

    });

Upvotes: 1

Related Questions