jQuery异步问题未定义值

时间:2015-06-06 22:54:08

标签: javascript jquery asynchronous promise jquery-deferred

我在使用Javascript的异步功能时遇到了困难。 下面显示的代码到目前为止我几乎完整的代码,我无法让它工作。

我试图使用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();
});
};

2 个答案:

答案 0 :(得分: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');
};

答案 1 :(得分: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命名空间。
  • " Async"有效方法的后缀在bluebird中有一个先例
  • 从我对EVDB.API的理解,EVDB.API.call()几乎所有事情都是如此,因此单一方法EVDB.API.callAsync()。如有必要,可以在EVDB.API
  • 中添加更多异步方法
  • 您可以选择使用专用的promise lib,例如bluebirdwhen.js来代替jQuery,除了包含lib之外,上述代码的mods也会很小。

现在,您可以致电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);
});