Функция Javascript не возвращает значение - PullRequest
3 голосов
/ 22 февраля 2012

Я вызываю функцию со следующим кодом:

var resultz = nsEditor.updateStringCall(debtID, column2Change, value2Change, 4, 10);

Функция, которая вызывается, но не возвращает значение

        updateStringCall: function(pdebtID, pcolumn2Change, pvalue2Change, pmin, pmax){
try {
    var resultz2 = 0;
    $.ajax({
        type: "POST",
        url: "Components/MintLibraries.cfc",
        dataType: "json",
        cache: false,
        data: {
                method: 'StringUpdate',
            val2Change: pvalue2Change.trim(),
            debtID: pdebtID,
            column2Change: pcolumn2Change,
            greaterThan: pmin,
            lesserThan: pmax,
            returnFormat: "json"
        },
        success: function(response) {
                       resultz2 = 1;
          return resultz2;
        },  //end done
        error: function(jqXHR, textStatus, errorThrown){
           resultz2 = 0;
                       return resultz2;
                }); //end ajax call
} catch (e) {
    resultz2 = 0;
    return resultz2;
}  //end trycatch

}, // end updateStringCall

Эта функция использует .ajax для вызова метода Cfc Coldfusion StringUpdate:

<cffunction name="StringUpdate" access="remote" output="false" returntype="any" >    
     <cfargument name="val2Change" type="string"  required="true" />
     <cfargument name="debtID"  type="string"  required="true" />
     <cfargument name="column2Change"  type="string"  required="true" />
     <cfargument name="greaterThan"  type="numeric"   required="false" />
     <cfargument name="lesserThan"  type="numeric"  required="false" />
     <cfset var debt2Pass = int(val(arguments.debtID)) />
     <cfset var updQuery = "" />
     <cfset var retValue = 0 />
     <cfset var iVal = 0 /><cfset var valError = '' />
    <cftry>

        <cfquery name="updQuery" datasource="#application.datasource#" result="qResults"    >
                Update dmf set #arguments.column2Change# =
                 <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.val2Change#"/>
                 where DebtID = 
                 <cfqueryparam cfsqltype="cf_sql_smallint" value="#arguments.debtID#"/>
        </cfquery> 
        <cfset retValue = 1 />    
     <cfcatch type="Any" >
                <cfset thrown = ThrowCFError(405,'debug',  'Error updating ' &  arguments.DebtID,arguments.val2Change & ', ' &  arguments.debtID & ',' & arguments.column2Change)  />
                  <cfset retValue = 0 />
         </cfcatch>
         </cftry>
    <cfreturn retValue />
</cffunction>

Запрос выполняется успешно, но функция js не возвращает значение (оно отображается как неопределенное). Даже если получит ошибку, я думаю, что я учел это достаточно, чтобы хотя бы получить возвращаемое значение.

Идеи?

Ответы [ 2 ]

17 голосов
/ 22 февраля 2012

Функция не возвращает значение, потому что return в вашем методе встроены в функции обратного вызова. Они возвращаются только из этих обратных вызовов, а не из вашей основной функции. Рассмотрим, например, ваш «успешный» обратный вызов:

success: function(response) {
    resultz2 = 1;
    return resultz2;
}

Это return только что вернулось из функции success ... Оно не всплывает до вашей функции updateStringCall.

Причина, по которой он должен работать таким образом, заключается в том, что вызовы ajax являются асинхронными. Ваш метод возвращает немедленно , пока запрос происходит в фоновом режиме. Поэтому, чтобы получить возвращаемое значение, вы должны передать обратный вызов, у которого есть доступ к значению, когда он будет готов, а затем вызвать обратный вызов из обратных вызовов ajax вместо возврата значения.

Поэтому измените определение вашего метода следующим образом:

// Note I added a "callback" parameter
function(pdebtID, pcolumn2Change, pvalue2Change, pmin, pmax, callback) { ... }

А затем в ваших обратных вызовах ajax, вызовите его вместо возврата значения:

success: function(response) {
    resultz2 = 1;
    callback(resultz2);
},
error: function(jqXHR, textStatus, errorThrown) {
    resultz2 = 0;
    callback(resultz2);
});

Наконец, передайте обратный вызов при вызове этого метода:

nsEditor.updateStringCall(debtID, column2Change, value2Change, 4, 10, function(resultz) {
    // Do something with resultz
});

И последнее замечание: если вы собираетесь использовать это одеяло, вы должны изменить это, чтобы использовать также обратный вызов:

catch (e) {
    resultz2 = 0;
    callback(resultz2);
}

Но на самом деле, я бы рекомендовал просто взять эту попытку / поймать все вместе. Я не вижу, как это может быть полезным здесь. Это будет скрывать только реальные проблемы с кодом, который уже имеет лучшую структуру для обработки ошибок. Я подозреваю, что вы просто добавили туда, чтобы отладить эту проблему возврата, но если она уже была, просто удалите ее.

Это мир функционального программирования, управляемого событиями! Это очень распространенная структура в JavaScript.

2 голосов
/ 22 февраля 2012

Ajax-вызовы являются асинхронными.Вам придется работать с вашим результатом из обратного вызова $ .ajax ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...