Appcelerator: проблема с переменной областью видимости

#javascript #appcelerator-mobile

#javascript #appcelerator-мобильный

Вопрос:

Я использую следующий код в Titanium Appcelerator для подключения к удаленному хосту:

 var connect_remote = function(url)
{
    /*
     * make sure that the Device is connected before initiate process as we don't want to force
     * the user to open remote stream just for sake of new entries
     */
     //alert("In Func"   is_connected());
     var d_data = null;
     if(is_connected())
     {

         var c = Titanium.Network.createHTTPClient();
         var data = null;
         c.setTimeout(10000);
         c.onload = function()
            {
                if (c.status == 200 )
                {
                    data = this.responseData;
                    Titanium.App.Properties.setString('returnData',data);
                }
            };

        c.error = function(e)
        {
            alert("Error = " e.error);
        }
        c.open('GET',url);
        c.send();
     }
}
  

Я хочу вернуть значение переменной data, которая должна сохранять значение ответа, чтобы я мог использовать, но она всегда возвращает null или undefined. Как мне вернуть из нее значение data?

Комментарии:

1. Вы должны уточнить, что вы подразумеваете под «возвращением значения данных «. Это сбивающее с толку утверждение, учитывая тот факт, что в JavaScript return оператор важен. Если вы просто имеете в виду, что хотите использовать значение, и что вызов Titanium, который вы выполняете для «setString()», является единственной проблемой, что ж, вам следует уточнить.

Ответ №1:

Не совсем понятно, что вы имеете в виду, но я думаю, что вы хотите, чтобы ваша функция «connect_remote ()» возвращала вам некоторое значение. Вы не можете этого сделать в асинхронной среде, подобной вашей. Вместо этого вы можете передать функцию в «connect_remote()», которой может быть передано значение «data» при запуске обработчика «onload».

 var connect_remote = function(url, handler)
{
    /*
     * make sure that the Device is connected before initiate process as we don't want to force
     * the user to open remote stream just for sake of new entries
     */
     //alert("In Func"   is_connected());
     var d_data = null;
     if(is_connected())
     {

         var c = Titanium.Network.createHTTPClient();
         var data = null;
         c.setTimeout(10000);
         c.onload = function()
            {
                if (c.status == 200 )
                {
                    data = this.responseData;
                    Titanium.App.Properties.setString('returnData',data);
                    handler(data);
                }
            };

        c.error = function(e)
        {
            alert("Error = " e.error);
        }
            c.open('GET',url);
        c.send();
     }
}
  

Комментарии:

1. Неясно, какая функция мне нужна, чтобы возвращать значение данных ответа; либо обработчик, либо connect_remote, либо я сохраняю значение в некотором глобальном var?

2. Хорошо, позвольте мне сформулировать это так: если вам где-то нужен return оператор, например return data; , в функции «onload», что ж, вы не можете этого сделать — функция «onload» вызывается асинхронно , поэтому ей негде возвращать значение — другими словами, нечего «перехватывать» возвращаемое значение. Но вы можете передать через функцию, как в моем примере.

3. Я могу понять, что из-за асинхронной природы невозможно предсказать, когда поступит значение, следовательно, не удается получить значение, даже выполняя функцию ‘connect_remote’. Значение обработчика действительно извлекает значение, но все решение не было бы таким общим, поскольку я хочу сделать «url» динамическим и извлекать нужные данные, и для каждого HTTP-запроса мне пришлось бы повторять всю логику

Ответ №2:

Попробуйте «data = c.responseData» вместо «data = this.responseData». Просто дикое предположение, основанное на этом