2009-07-07 13 views
2

データを返す必要のある関数にデータを戻すときに問題が発生しました。以下のコード:Javascriptで元の呼び出し元関数にデータを返す方法はありますか?

function ioServer(request_data, callback) 
{ 
    $.ajax({ 
     cache: false, 
     data: "request=" + request_data, 
     dataType: "json", 
     error: function(XMLHttpRequest, textStatus, errorThrown){}, 
     success: function(response_data, textStatus){ 
      callback(response_data); 
      }, 
     timeout: 5000, 
     type: "POST", 
     url: "/portal/index.php/async" 
    }); 
} 

function processRequest(command, item, properties) 
{ 
    var request = {}; 
    request.command = command; 
    request.item = item; 
    request.properties = properties; 
    var toServer = JSON.stringify(request); 
    var id = ioServer(toServer, processResponse); 
    return id; 
} 

function processResponse(fromServer) 
{ 
    if (fromServer.response == 1) 
    { 
     return fromServer.id; 
    } 
} 

このコードを呼び出すには、別の関数内でprocessRequest関数を呼び出します。要求を送信し、応答を取得するだけでうまくいきます。しかし、私はresponseからprocessRequest関数に値 'id'を返す必要があるので、その値を呼び出し側に返すことができます。私が続ける限り、processResponseの戻り値は$ .ajaxに戻りますが、さらにそれをprocessRequestに戻す必要があります。

BTW ifResponseのif文は、リクエストが許可されているかどうかを示すためにサーバ側のPHPスクリプトによって設定された値を指します(たとえば、ユーザがログインしていない場合はfromServer.responseは0になります)。 $ .ajaxオブジェクトの成功/エラールーチンとは何の関係もありません。

多くのご協力ありがとうございます。

@Jani:応答に感謝しますが、もう少し明確にすることはできますか? 「ID」が必要とされる機能は、次のコードを持っています

$(#tabs).tabs('add', '#tab-' + id, 'New tab'); 

私はprocessResponse機能でコードのこの部分を実行してみてくださいと言っていますか?それは私がやりたいことではないからです。これらの機能は、サーバー側の状態を維持するための万能のソリューションとなります。それで、私はこのコードをそこに置くことを避けました。

答えて

3

Tonyからコメントがありませんでしたので、彼が提案していることの詳細を追加してください。

ご存じのように、$ .ajaxメソッドが非同期であるため、$ .ajax呼び出しが行われるとすぐにprocessRequest関数が完了します。ですから、processRequestの呼び出し側にタスクが完了したことを通知するにはどうすればよいですか?

単純に、processRequestの呼び出し側に 'コールバック関数'を提供するようにお願いします。 processRequestは、ajax出力を受け取ったときはいつでもこの関数を呼び出します。 tonyのコードでは、これはprocessRequest関数の最後の引数です。

だからあなたの呼び出し元のコードは今

function tabMethod() 
{ 
    processRequest('command', 'item', 'properties', 
        function(id) 
        { 
        if(id == null) 
        { 
          alert('There is a problem!'); 
          return; 
        } 
        $('#tabs').tabs('add', '#tab-' + id, 'New tab'); 
        }); 


}; 
+0

はい、より明示的な使用の説明に感謝します! –

+0

そしてすばらしい解明のための投票... –

3

これは非同期要求であるため、このような値は直接返されず、不可能です。

これにアプローチする方法は、動作しない戻り値を持つことを試みるのではなく、取り出したデータに対して必要なアクションを実行するメソッドを持つことです。

5

私は多分、これはあなたが探しているものに近いと思います...

function ioServer(request_data, callback) 
{ 
    $.ajax({ 
     cache: false, 
     data: "request=" + request_data, 
     dataType: "json", 
     error: function(XMLHttpRequest, textStatus, errorThrown){}, 
     success: function(response_data, textStatus){ 
       processResponse(response_data, callback); 
       }, 
     timeout: 5000, 
     type: "POST", 
     url: "/portal/index.php/async" 
    }); 
} 

function processRequest(command, item, properties, callback) 
{ 
    var request = {}; 
    request.command = command; 
    request.item = item; 
    request.properties = properties; 
    var toServer = JSON.stringify(request); 
    ioServer(toServer, callback); 
} 

//internal callback to handle response code 
function processResponse(fromServer, callback) 
{ 
    if (fromServer.response == 1) 
    { 
     //call the callback with the id 
     callback(fromServer.id); 
    } 
    else 
    { 
     //You have to remember to call the callback no matter what 
     //or the caller won't know when it's complete 
     callback(null); //or some other "didn't get a valid response" value 
    } 
} 
+0

コードの提案と呼び出しコードの外観の説明が追加されました。あなたが気にしないことを願っています。 http://stackoverflow.com/questions/1094716/how-does-one-return-data-to-the-original-caller-function-in-javascript/1095251#1095251 – SolutionYogi

+0

返信したい場合はどうすればよいですか? ioServerのprocessRequestと2つ以上の関数がioServerを呼び出している場合、私はRequestee関数名についてよくわかりません????? – dnxit

0

の代わりに、以前に掲載誰か他の人のような同期呼び出しをシミュレートするために、ブロッキング実装、ちょうどAJAXは、同期と更新自体を呼び出す作りますあなたの成功ラッパー:

function ioServer(request_data, callback) { 
    var response = null; 
    $.ajax({ 
     cache: false, 
     data: "request=" + request_data, 
     dataType: "json", 
     error: function(XMLHttpRequest, textStatus, errorThrown){}, 
     success: function(response_data, textStatus) { 
       response = callback(response_data); 
     }, 
     timeout: 5000, 
     type: "POST", 
     url: "/portal/index.php/async", 
     async: false 
    }); 

    return response; 
} 

編集:有用ですが、これは「普通の」AJAX使用の穀粒とは異なります。代わりにあなたのアプローチを変更することをお勧めします。

+1

ajaxリクエストを迅速に完了できなかった場合、ブラウザがフリーズする可能性があるため、同期呼び出しを行いたくない。 – SolutionYogi

+0

@solutionyogi Hah、そう、あなたがコメントしたときに私はそのことについて編集していた。しかし、私は(慎重に)ブラウザの凍結の問題なしでこれをやってきました。私が知る限り、JavaScriptは単にブロックを待つだけで、何も実行しません。 –

1

恐ろしいのようになります!助けてくれてありがとう、それは今の魅力のように働く。そして私はコールバックをより良く使うことを学んだ。

createTab('#tabs'); // I'm using JQuery UI to handle tabs  

function createTab(parent_element){ 
      var name = {}; 
      name.name = "New tab"; 
      var position = {}; 
      position.position = $(parent_element).tabs('length') + 1; 
      var properties = new Array(); 
      properties[0] = name; 
      properties[1] = position; 
      processRequest(1, 1, properties, 
         function(id) 
         { 
         if(id == null) 
         { 
           alert('There is a problem!'); 
           return; 
         } 
         $('#tabs').tabs('add', '#tab-' + id, 'New tab'); 
         }); 
     } 

function ioServer(request_data, callback) 
{ 
    $.ajax({ 
     cache: false, 
     data: "request=" + request_data, 
     dataType: "json", 
     error: function(XMLHttpRequest, textStatus, errorThrown){}, 
     success: function(response_data, textStatus){ 
       processResponse(response_data, callback); 
       }, 
     timeout: 5000, 
     type: "POST", 
     url: "/portal/index.php/async" 
    }); 
} 

function processRequest(command, item, properties, callback) 
{ 
    var request = {}; 
    request.command = command; 
    request.item = item; 
    request.properties = properties; 
    var toServer = JSON.stringify(request); 
    ioServer(toServer, callback); 
} 

//internal callback to handle response code 
function processResponse(fromServer, callback) 
{ 
    if (fromServer.response == 1) 
    { 
     //call the callback with the id 
     callback(fromServer.id); 
    } 
    else 
    { 
     //You have to remember to call the callback no matter what 
     //or the caller won't know when it's complete 
     callback(null); //or some other "didn't get a valid response" value 
    } 
} 

ページのリストの最後に新しいタブが追加されます。これは、私が望んでいたのと同じように、PHPとMySQLのサーバサイドにも格納されています。

もう一度おねがいします!

関連する問題