iT邦幫忙

1

ajax 回傳值問題請教

您好:
如以下程式碼:
我想在 set_prc 中,呼叫 get_realprc 的ajax,回傳 return rtn;
var p= get_realprc(typex, rowIndex, str_arr);
但不管async: true, 或 async: false,
他都未等get_realprc,就 回傳了

請問,這是否有方法解決!
謝謝!

 function set_prc(typex, rowIndex) { 
            

            var arr4update = new Array(); //要傳遞的陣列

            var objPost;


            //--單筆資料
            objPost = new Object();
                       
            objPost.prcdate = makedate_val;
          
   
            arr4update.push(objPost);  // 傳入陣列

            let str_arr = JSON.stringify(arr4update);
          
           var p=  get_realprc(typex, rowIndex, str_arr);

         //  alert(p);


        }//---
 function get_realprc( typex, rowIndex,str_arr) {

            let result = "";
            let rtn = 0.0;

          
            setTimeout(function () {

                /*執行批次處理*/
                $.ajax({
                    type: "POST",
                    url: '../handler/jqDataHandle.ashx?RemoteName=s_XX',  //
                    data: {
                        mode: "method",
                        method: "get_realprc",
                        parameters: str_arr
                    },
                    cache: false,
                    async: true,
                    success: function (data) {


                        result = data; //這邊回傳字串

                        var obj = JSON.parse(result);



                        let x = obj.Table1[0];

                        rtn = x.prc_m;
                       
  					    set_amt(typex, rowIndex, rtn);
                       
                    }
                });

            }, 1);


            return rtn;

        }//----get_realprc
 function set_amt( typex, rowIndex, prc_m) {  //----設定值

            if (typex == 'D') {
                alert('D')
            } else if (typex == 'P') {

                alert ('P')
            }

            //alert(rowIndex +'-'+prc_m);
        }//-- set_amt

tunin iT邦新手 4 級 ‧ 2021-03-23 18:36:53 檢舉
你可能要先想一下 get_realprc() 中的 setTimeout 是為了什麼加進去的??
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
2
小魚
iT邦大師 1 級 ‧ 2021-03-23 19:28:51

setTimeout是非同步的,
ajax也是非同步的,(雖然好像可以要求同步, 但是有時候好像會出錯)
在你執行完get_realprc到 return rtn 的時候,
根本沒有處理到setTimeout跟ajax,
通常非同步是拿來改變畫面(如畫面資料等等的),
或是改變 hidden 資料的,
就算改變了全域變數也要等執行完之後再呼叫才有效果,
(問題是你不知道它甚麼時候執行完,
這還牽扯到網路的速度)

6
japhenchen
iT邦超人 1 級 ‧ 2021-03-24 08:06:44

不要讓使用ajax的函式做return value的動作,能做的,只有在ajax的.done或.success裡再去調用別的動作,而不是讓主程式去等待回傳值才走下一步,不是不可以改成 async await,而是這樣就跟桌面環境一樣,失去了網頁非同步化設計的優點...會為了某件動作而整個卡住..

使用 async / await / promise 的用法
https://www.oxxostudio.tw/articles/201908/js-async-await.html
(可能要考慮到瀏覽器的相容性)

javascript 裡的老大(主程式或事件),叫了小弟a(某個function)去買一包菸(ajax),且要小弟把菸拿去給另外一個幫的老K,點菸的時候,一槍把那個老K給X了

而不是把買回來的菸拿回來給自己的老大,由老大自己去開這一槍X了另外一個幫的老K

老大不用"等"這包菸買回來(return 菸),也不用去親自動這個手,把任預全部委任給那個小弟function a就對了

淺水員 iT邦大師 6 級 ‧ 2021-03-24 09:54:14 檢舉

async + await 其實還是非同步,並不會卡瀏覽器
本質上跟 promise 一樣,只是寫法上看起來很像同步

我真的沒有在ajax或setTimeout的function做return value的動作,要嘛委派,要嘛以ajax取得的dataType另外呼叫其他function,事情就簡單多了

0
Lena_Yang
iT邦新手 5 級 ‧ 2021-03-24 08:26:01

你如果下console.log的話,就會發現return會在get的success前面執行,最簡單的方式是把取得值之後要做的動作直接放在get_realprc的success裡面執行,這樣流程上就是順的

2

其實你寫的 setTimeout 是多餘的。
要先了解一下AJAX是屬於非同步運行的模式。

何謂非同步運行,就是下命令完之後。其JAVASCRIPT其實並不會等待命令是否執行完了。
所以這也是為何AJAX會有 success 這一類的事件回應。

簡單來說,如果要做到同步回應的情況下有兩種方式。
其一是強迫為同步運行,但這一招有時會有問題。
第二招就是採用backCall的方式。

可將

function get_realprc( typex, rowIndex,str_arr)

先改成

function get_realprc( typex, rowIndex,str_arr,callFunc)

其setTimeout可以拿掉了。
然後在其 AJAX內success 改成

success: function (data) {
  callFunc(data)                     
}

這樣子你在呼叫get_realprc可以改成

get_realprc(typex, rowIndex, str_arr,function(data){
    ....這邊就寫回傳後要處理的事...
});

當然,我以上只是簡單的教一下原理。

noway iT邦研究生 4 級 ‧ 2021-03-24 21:48:50 檢舉

謝謝 大家

我要發表回答

立即登入回答