[英]JavaScript Promise and Promise.all(array) executed before array fulfilled
[英]The JavaScript Promise callback is executed before the Promise itself
目前我正在處理一個 Oracle APEX 頁面,其中包含用於放置文檔參數的表單。 我的目標是完善機制,根據數據庫中的某些信息定義表單的哪些字段可供用戶使用,哪些字段不可用。
我制作了 PL/SQL 過程並編寫了 JavaScript 函數(以及 AJAX 進程)來幫助我解決這個任務,但是當我需要執行一些 Z686155AF75A60A0F6E9D80C1 后的可用字段時我遇到了問題編輯例如,有時應刷新與表單綁定的某些報表或應從 HTML 頁面中刪除某些輔助元素)。 換句話說,我有function enableFields (在參數頁面加載時執行),它必須執行enableFieldsBase ,然后在輸入參數中定義回調function callbackFunc ,但經過一些測試我發現后者在前者之前執行盡管使用了 JavaScript 承諾。
這是 JavaScript function 使用數據庫中的信息使表單字段可用(或不可用):
function enableFieldsBase(){
var page = 'P' + $v('pFlowStepId') + '_'; //define the page
var docID = $v(page + 'DOC_ID'); //define the document
//get the information which fields are available and which are not
$.post('wwv_flow.show',
{'p_request' : 'APPLICATION_PROCESS=DOC_ENABLE_FIELDS',
'p_flow_id' : $v('pFlowId'),
'p_flow_step_id' : $v('pFlowStepId'),
'p_instance' : $v('pInstance'),
'x01' : docID},
function(pData) {
var res = eval('(' + pData+ ')');
if (res.status == "OK") {
//get the array of objects containing the shortened element names and the availability sign
var props = res.data;
//open or close the elements for edit
for (var i = 0; i < props.length; i++){
if (props[i].enabled == 1) apex.item(page + props[i].prop).enable();
else apex.item(page + props[i].prop).disable();
}
} else {
//…the code for catching the exceptions…
}
});
}
而這就是JavaScript function,它不僅執行了前一個,還考慮到了回調function:
function enableFields(callbackFunc){
var page = 'P' + $v('pFlowStepId') + '_';
//check if the variable callbackFunc is really a function
if (callbackFunc != undefined && typeof(callbackFunc) != 'function'){
//…the code for catching the exceptions…
}
if (callbackFunc != undefined){
var promise1 = new Promise(function(resolve,reject){
enableFieldsBase();
return resolve(true);
});
$.when(promise1).done(function(){
callbackFunc();
});
} else {
enableFieldsBase();
}
}
所以,我的問題如下:我做錯了什么? 是否可以不將回調 function 顯式放入enableFieldsBase的代碼中?
我使用 Oracle 11g 和 Oracle APEX 4.2.6.00.03。
問題是您同步調用resolve
,而無需等待發布請求完成。 所以 promise 立即解決。
相反,您應該使用$.post
開箱即用返回的 promise:
function enableFieldsBase(){
var page = 'P' + $v('pFlowStepId') + '_'; //define the page
var docID = $v(page + 'DOC_ID'); //define the document
//make sure to RETURN the result of the `$.post` call, and chain a `then` method call
return $.post('wwv_flow.show',
{'p_request' : 'APPLICATION_PROCESS=DOC_ENABLE_FIELDS',
'p_flow_id' : $v('pFlowId'),
'p_flow_step_id' : $v('pFlowStepId'),
'p_instance' : $v('pInstance'),
'x01' : docID}).then(function(pData) { // Use the `then` method
var res = eval('(' + pData+ ')');
if (res.status == "OK") {
//get the array of objects containing the shortened element names and the availability sign
var props = res.data;
//open or close the elements for edit
for (var i = 0; i < props.length; i++){
if (props[i].enabled == 1) apex.item(page + props[i].prop).enable();
else apex.item(page + props[i].prop).disable();
}
} else {
//…the code for catching the exceptions…
}
});
}
在調用代碼中:
if (callbackFunc != undefined){
enableFieldsBase().then(callbackFunc);
} else {
enableFieldsBase();
}
正如 jonrsharpe 在下面的評論中指出的那樣,如果您傳遞給then
一個不可調用的參數(如undefined
),就好像您根本沒有傳遞回調。 因此,您可以進一步簡化為:
enableFieldsBase().then(callbackFunc);
最好將callbackFunc
參數放到enableFields
中,然后返回 promise。 然后enableFields
的調用者應該自己決定是否要鏈接then
調用它(或使用await
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.