Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jQuery:是否保存异步调用结果以供以后使用?_Javascript_Jquery_Asynchronous_Odoo 8_Jquery Deferred - Fatal编程技术网

Javascript jQuery:是否保存异步调用结果以供以后使用?

Javascript jQuery:是否保存异步调用结果以供以后使用?,javascript,jquery,asynchronous,odoo-8,jquery-deferred,Javascript,Jquery,Asynchronous,Odoo 8,Jquery Deferred,我有以下实施: instance.web_calendar.CalendarView.include({ handle_special_dates: function(date, cell){ var def = $.Deferred(), model = new instance.web.Model('calendar.special'); model.call('get_special_d

我有以下实施:

    instance.web_calendar.CalendarView.include({
        handle_special_dates: function(date, cell){
            var def = $.Deferred(),
                model = new instance.web.Model('calendar.special');
            model.call('get_special_dates').then(function(result){
                // Transform date strings into date obj valueOf result.
                var new_obj = {}
                for (key in result){
                    if (result.hasOwnProperty(key)){
                        var dt_value = new Date(key).valueOf();
                        // Set new key as date.ValueOf() and use
                        // special date name as value.
                        new_obj[dt_value] = result[key]
                    }
                }
                return new_obj;
            }).then(function(result){
                // We stringify value, because object stringifies keys
                // automatically.
                var dt_value = String(date.valueOf())
                // Check if date value is in special dates keys.
                // We check for -1, because it actually returns index,
                // not a boolean value.
                if ($.inArray(dt_value, Object.keys(result)) != -1){
                    var div = $(
                        '<div />',
                        {
                            "class": 'fc-special-day',
                            text: result[dt_value]
                        }
                    )
                    cell.children('div').prepend(div)
                    // Set special day background
                    cell.addClass('fc-special-background')

                }
            })
            return def;
        },
        get_fc_init_options: function(){
            var self = this;
            fc_options = this._super()
            if (this.special_dates){
                return $.extend({}, fc_options, {
                    dayRender: function(date, cell){
                        self.handle_special_dates(date, cell)
                    }
                });
            } else {
                return fc_options;
            }
        },
    })
}
instance.web\u calendar.CalendarView.include({
处理特殊日期:函数(日期,单元格){
var def=$.Deferred(),
model=newinstance.web.model('calendar.special');
model.call('get_special_dates')。然后(函数(result){
//将日期字符串转换为结果的日期obj值。
var new_obj={}
用于(输入结果){
if(result.hasOwnProperty(key)){
var dt_value=新日期(键).valueOf();
//将新键设置为date.ValueOf()并使用
//特殊日期名称作为值。
新建对象[dt_值]=结果[键]
}
}
返回新的_obj;
}).然后(函数(结果){
//我们字符串化值,因为对象字符串化键
//自动地。
var dt_value=String(date.valueOf())
//检查日期值是否在特殊日期键中。
//我们检查-1,因为它实际上返回索引,
//不是布尔值。
if($.inArray(dt_值,Object.keys(结果))!=-1){
var div=$(
'',
{
“班级”:“fc特殊日”,
文本:结果[dt_值]
}
)
单元格.children('div').prepend(div)
//设置特殊的日子背景
cell.addClass('fc-special-background')
}
})
返回def;
},
get_fc_init_选项:函数(){
var self=这个;
fc_options=这个。_super()
如果(此特殊日期){
返回$.extend({},fc_选项{
dayRender:函数(日期、单元格){
self.handle\u特殊日期(日期,单元格)
}
});
}否则{
返回fc_选项;
}
},
})
}
handle\u special\u dates
函数调用方法,该方法在系统后端定义(这是异步调用),解析结果并使用它检查是否需要修改日历的
单元格

问题是
then
两个部分的调用次数与要检查的单元格的调用次数相同。这有点笨重,因为我只需要调用后端一次,然后对所有单元格使用结果

基本上,首先
然后
(调用
get\u special\u dates
backend方法的部分)应该只调用一次。我试图分离该功能,但在
daydrender
需要它之前调用它。换句话说,它永远不会在需要时调用:)

有没有什么方法可以等待第一部分完成,而不是像现在这样称呼它?我的意思是它是异步调用,但现在我想它甚至比同步调用还要慢

另外,我知道JS中有新的
Promise
功能,但是这个版本中的Odoo目前使用的是jQuery deferred,所以我也在使用它

更新

为了更好地解释这种情况,我将尝试描述结构、目前所做的工作以及问题所在

这个系统有两部分,后端(由Python管理)和前端(Javascript)

后端管理前端可以使用的数据。具体来说,后端中有一个名为
get\u special\u dates
的方法。它返回在名为
calendar\u special
的特定表中输入名称的日期。因此,如果有人输入任何此类日期,它将返回其日期字符串表示形式(和名称)。例如,我们可以输入日期
2017-04-16
,并将其称为
Easter

现在,当Javascript部分加载日历界面时,它会检查所有当前可见的日历日期,并与
get\u special\u dates
返回的日期进行比较。如果比较的日期匹配,它将在日历中标记这些日期

但问题是
获取特殊日期
现在被调用的次数与每个日期/单元格对的检查次数相同。假设我们在一个月内有30个日期,并且我们看到该月有30个日期,它将调用
get_special_dates
30次,而实际上只有一个调用就足够了(因为所有日期/单元格对检查的后端日期都是相同的)。但我需要保存结果,以便在所有日期/单元格对中重复使用(或者使用适合于
延迟的
的其他方法)

基本上,它会检查每个可见的日历日期,并与后端输入的日期进行比较。

也许这张图片更能说明这个功能是如何工作的。背景为绿色的日期实际上是作为特殊日期输入后端的日期


你所问的实际上是,“我如何缓存承诺?”

简单的答案是“将其分配给适当范围内的成员,在需要时可以从中访问它。”

这里,“适当范围内的成员”(不一定是唯一的成员)是
handle\u special\u dates()
是其属性的对象,该属性(除非
handle\u special\u dates()
以奇数方式调用)将是
this
handle\u special\u dates()

除了缓存promise之外,您还可以通过在缓存点链接两个THEN中的第一个THEN来执行一次
new_obj
转换

specialDatesPromise: null, // not strictly necessary but makes the cache overt. 
handle_special_dates: function(date, cell) {
    // if promise doesn't already exist, call() and cache
    if(!this.specialDatesPromise) {
        this.specialDatesPromise = (new instance.web.Model('calendar.special')).call('get_special_dates')
        .then(function(specialDates) {
            // for economy of effort, perform transform at point of caching
            var new_obj = {};
            $.each(specialDates, function(key, value) {
                new_obj[new Date(key).valueOf()] = value;
            });
            return new_obj;
        });
    }
    // Now use the cached promise - it may be newly or previously cached - doesn't matter which.
    return this.specialDatesPromise.then(function(result) {
        var dt_value = String(date.valueOf());
        if (result[dt_value] !== undefined) {
            cell.addClass('fc-special-background').children('div').prepend($('<div/>', {
                'class': 'fc-special-day',
                'text': result[dt_value]
            }));
        }
    });
},
specialDatesPromise:null,//严格来说不是必需的,但会使缓存公开。
处理特殊日期:函数(日期,单元格){
//如果承诺不存在,则调用()并缓存
如果(!this.specialDatesPromise){
这是我的生日礼物