2015-06-06 4 views
0

У меня возникают трудности с асинхронными функциями Javascript. Код, отображаемый ниже, - это почти весь код, который у меня есть, и я не могу заставить его работать.jQuery асинхронная проблема неопределенное значение

Я пытаюсь использовать Eventful API для извлечения некоторых данных с сервера и отображения его в моем интерфейсе, который создается jQuery.

Таким образом, проблема заключается в следующем: функция поиск, который вызова функции Eventful.prototype.searchanje всегда заканчивается с неопределенным значением, а через несколько секунд, функция searchanje консоли регистрирует фактические/полученных данных построена.

Я довольно новичок в jQuery, и мне было интересно, существует ли какой-либо «шаблон» для обработки этих вещей, конкретно для ожидания, пока функция не вернет значение, а затем продолжит следующие операции. До сих пор я пробовал использовать отложенные и обещания и читал довольно много руководств и ответов stackoverflow на похожие темы, но я не могу заставить его работать правильно. Или, если отложенные и обещания - это правильный путь, не могли бы вы показать мне, как это должно быть сделано?

Заранее спасибо

'use strict'; 

function Eventful(_name) { 
var name = _name; 
var appKey = 'appKey'; 
var that = this; 

return { 
    getName: function() { 
     return name; 
    }, 
    getAppKey: function() { 
     return appKey; 
    }, 
    search: function() { 
     that.searchanje(appKey).then(function(oData) { 
      console.log('oData'); 
     }); 
    } 
}; 
} 

Eventful.prototype.searchanje = function(appKey) { 
var oArgs = { 
    app_key: appKey, 
    q: 'sport', 
    where: 'Zagreb', 
    date: '2013061000-2015062000', 
    page_size: 5, 
    sort_order: 'popularity', 
}; 

EVDB.API.call('/events/search', oArgs, function(oData) { 
    console.log(oData); 
    return oData(); 
}); 
}; 
+1

возможно дубликат [Как вернуть ответ от асинхронного вызова?] (Http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous- звоните) –

ответ

0

На линии

EVDB.API.call('/events/search', oArgs, function(oData) { 

вы передаете функцию CALLBACK. Эта функция (ту, которая начинается function(oData)) не выполняется немедленно. Он выполняется асинхронно, когда возвращается результат вызова API.

Попробуйте ввести console.log() заявления вокруг вашего кода и посмотреть, как они отображаются в консоли. Например:

function Eventful(_name) { 
    var name = _name; 
    var appKey = 'appKey'; 
    var that = this; 

    return { 
     getName: function() { 
      return name; 
     }, 
     getAppKey: function() { 
      return appKey; 
     }, 
     search: function() { 
      console.log('Search function called'); 
      that.searchanje(appKey).then(function(oData) { 
       console.log('searchanje returned with data:'); 
       console.log('oData'); 
      }); 
     } 
    }; 
} 

Eventful.prototype.searchanje = function(appKey) { 
    console.log('function searchanje being called with appKey: ', appKey); 
    var oArgs = { 
     app_key: appKey, 
     q: 'sport', 
     where: 'Zagreb', 
     date: '2013061000-2015062000', 
     page_size: 5, 
     sort_order: 'popularity', 
    }; 

    console.log('Calling EVDB.API.call'); 
    EVDB.API.call('/events/search', oArgs, function(oData) { 
     console.log('EVDB.API callback executing with data:'); 
     console.log(oData); 
     return oData(); 
    }); 
    console.log('finished calling EVDB.API.call'); 
}; 
+0

ok, есть ли у вас какие-либо предложения, как поступить дальше? как ждать этого возвращаемого значения, а затем продолжить выполнение? – Zorkan

+0

@ Zorkan Да, вы «делаете материал» своими результатами внутри функции обратного вызова –

+0

- это не способ попасть в аддон? не конкретно для этих двух строк кода я встал здесь, но для более сложных проектов? – Zorkan

0

Интересно, если лучший путь вперед может быть «promisify» EVDB.API.call().

(function(app_key) { 
    var appKeyObj = { 'app_key': app_key }, 
    EVDB.API.callAsync = function(path, params) { 
     return $.Deferred(function(dfrd) { 
      EVDB.API.call(path, $.extend(appKeyObj, params), function(oData) { 
       if (oData.error === "1") { 
        //translate oData.status and oData.description into a javascript Error object 
        // with standard .name and .message properties. 
        err = new Error(oData.description); 
        err.name = oData.status; 
        dfrd.reject(err); 
       } else { 
        dfrd.resolve(oData); 
       } 
      }); 
     }); 
    }); 
})('myAppKey'); //hard-coded app key 

Примечание:

  • Глобальное пространство имена избежать путем:
    • с использованием прямоприменяемого анонимного обертку
    • расширяя EVDB.API пространства имен.
  • «Асинхронный» суффикс для promisified метода имеет precendent в Bluebird
  • От мало я понимаю из EVDB.API, EVDB.API.call() делает почти все, следовательно, единственный метод EVDB.API.callAsync(). Если необходимо, можно добавить дополнительные методы асинхронизации в EVDB.API
  • Возможно, вы захотите использовать выделенное обещание lib, такое как bluebird или when.js вместо jQuery. В дополнение к включению lib моды к вышеуказанному коду были бы незначительными.

Теперь, вместо звонка EVDB.API.call(path, params, callback), вы бы позвонили EVDB.API.callAsync(path, params), чтобы вернуть обещание.

var params = { 
    //app_key will be inserted automatically 
    q: 'sport', 
    where: 'Zagreb', 
    date: '2013061000-2015062000', 
    page_size: 5, 
    sort_order: 'popularity' 
}; 
EVDB.API.callAsync('/events/search', params).then(function(oData) { 
    console.log(oData); 
}, function(err) { 
    console.error(err); 
}); 
Смежные вопросы