您好:
如以下程式碼:
我想在 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
setTimeout是非同步的,
ajax也是非同步的,(雖然好像可以要求同步, 但是有時候好像會出錯)
在你執行完get_realprc到 return rtn 的時候,
根本沒有處理到setTimeout跟ajax,
通常非同步是拿來改變畫面(如畫面資料等等的),
或是改變 hidden 資料的,
就算改變了全域變數也要等執行完之後再呼叫才有效果,
(問題是你不知道它甚麼時候執行完,
這還牽扯到網路的速度)
不要讓使用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就對了
async + await 其實還是非同步,並不會卡瀏覽器
本質上跟 promise 一樣,只是寫法上看起來很像同步
我真的沒有在ajax或setTimeout的function做return value的動作,要嘛委派,要嘛以ajax取得的dataType另外呼叫其他function,事情就簡單多了
你如果下console.log的話,就會發現return會在get的success前面執行,最簡單的方式是把取得值之後要做的動作直接放在get_realprc的success裡面執行,這樣流程上就是順的
其實你寫的 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){
....這邊就寫回傳後要處理的事...
});
當然,我以上只是簡單的教一下原理。