Javascript 敲除是否异步执行模型绑定?如果是,我该如何预防?

Javascript 敲除是否异步执行模型绑定?如果是,我该如何预防?,javascript,jquery,knockout.js,Javascript,Jquery,Knockout.js,在下面的代码中,我正在更新我的knockout model属性SearchResults,然后重新计算html中所有列的大小。我知道\u resizeColumns功能工作正常。但是,它是在使用搜索结果更新DOM之前运行的。我已经通过用黄色更新所有div上的背景色来验证是否调用了\u resizeColumns。模型更新之前存在的div将设置为黄色,但搜索结果不是 $.ajax({ type: 'POST', url: 'foo.com', data: postData,

在下面的代码中,我正在更新我的knockout model属性
SearchResults
,然后重新计算html中所有列的大小。我知道
\u resizeColumns
功能工作正常。但是,它是在使用搜索结果更新DOM之前运行的。我已经通过用黄色更新所有div上的背景色来验证是否调用了
\u resizeColumns
。模型更新之前存在的div将设置为黄色,但搜索结果不是

$.ajax({
    type: 'POST',
    url: 'foo.com',
    data: postData,
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    processData: true,
    success: function(data) {
      model.SearchResults(data.d); // updates the DOM with the search results via knockout.js
      _resizeColumns();            // does not resize the columns because they haven't been added to the DOM yet
    },
    error: function() { alert('error'); }
});
搜索结果确实会添加到DOM中,就在我调用
\u resizeColumns

更新 我不认为knockout是异步运行的。我相信是web浏览器本身在异步更新DOM

更新2 当直接从
$(document.ready()
调用时,
\u resizeColumns()
函数可以工作

更新3
我有两个版本的
\u resizeColumns()
一个版本使用jquery选择器获取和设置宽度,另一个版本在获取宽度时存储到二维数组中,并在设置宽度时访问该二维数组。2d阵列版本执行速度更快。2d阵列版本也导致了我上面原始问题中的问题。只有jquery版本没有。您的问题的答案是否定的,Knockout不会异步执行绑定,除非您明确地强制它执行绑定。默认情况下,它将在转到下一条语句之前通知所有订阅者

可以这样看——

self.updateSomethings = function () {
    self.somethings.push(new something('William', 1234432));
    alert('binding complete');
}        

在我的应用程序中,我遇到了一个类似的问题——我需要在内容通过Knockout呈现之后设置列宽。我的解决方案是创建一个自定义绑定,我可以将它放在
元素上,每当更新表时,该元素都会更新(因为它绑定到相同的可观察数组)。当尝试同步运行绑定时,我遇到了麻烦,但它非常简单,可以异步运行。这是我的装订:

ko.bindingHandlers.fixColumnWidths = {
    update: function(element, valueAccessor) {
        if (ko.utils.unwrapObservable(valueAccessor())) {
            setTimeout(function() {
                $headings = $(element).find('thead th');
                if (!$headings.length) {
                    $headings = $(element.rows[0].cells);
                }
                $headings.width('').width(function(index, width) {
                    return width;
                });
            });
        }
    }
};

您的model.SearchResults()应该在继续运行_resizeColumns之前,将数据填入并提醒订阅它的任何人。要查看此操作,请发出警报(model.SearchResults);当警报暂停脚本执行时,您应该看到DOM中有数据。您是否考虑过根据ko计算属性调整列的大小?@PWKad问题是knockout的绑定运行异步,因此您不知道DOM何时将与新数据绑定,当发生这种情况时,无法转发回调方法来运行,我尝试订阅可观察对象,但每次都是在数据绑定之前而不是之后执行,很想知道如何知道绑定何时完成。@RoyiMindel您能参考支持绑定回调异步执行的文档吗?我从未见过异步处理的标准绑定,但可能我错了。@PWKad这个问题向您展示了它是异步处理的,我也遇到过同样的问题几次,您更新了一个可观察对象,在您对绑定到它的DOM元素做了一些工作之后,您的工作将在绑定生效之前进行,这意味着它是异步运行的,如果它是同步的-在数据反弹到DOM元素后会发生resizeColumns,但事实并非如此-存在问题检查出来后,我的问题是在它更改DOM元素后无法捕获可观察到的更新,在DOM恢复到新值之前订阅fire。-所以不是同一个问题,我收回它很高兴你能找到你的问题。祝你好运,享受淘汰赛,你会喜欢的