拒绝将jquery推迟作为预期控制流程不良做法的一部分?

时间:2016-06-01 05:24:54

标签: javascript jquery jquery-deferred

我有一个用于创建新对象和编辑现有对象的表单。该表单包含一些插件(日期选择器,jstree),我正在尝试使用jquery延迟来使加载更干净。这是我第一次尝试使用延迟对象。

我想要做的是首先加载表单,然后如果我正在编辑现有表单,我还想用现有值填充表单。我的成本看起来像这样(它是coffeescript,但我认为它非常易读)

    $.when(
            # These functions all return jquery.Deferred objects.
            getBookingDetails(id), buildJstree(), buildCalendar()
    ).then(
        # Editing an existing booking
        (bookingResponse, jstreeResponse_ignored, calendarResponse_ignored) =>
            # ... populate form with data from bookingResponse ...
            $("#name").val(bookingResponse[...])
            # etc., Rest is omitted
    ).fail(
        # Creating a new booking, so don't need to do anything more to the form.
        () ->
    )

因此,如果我正在编辑,我希望$ .when()能够解析并放入then()。如果我要创建一个新的预订,我会人为地导致$ .when()失败,就像这样

getBooking: (id) =>
    if id is null
        return $.Deferred().reject('id is null')

    return $.ajax({
        url        : base + "/api/v1/daily/id/#{id}"
        type       : "GET"
        contentType: "application/json"
        data       : {}
    })

但是我觉得这是错误的,因为如果$ .when()中的任何其他延迟对象失败,例如因为我的插件没有正确加载,所以我需要做额外的工作来检查这个错误,这只是感觉不正确。

如果我的方法确实不好,你能解释一下为什么吗?

如何正确地重组事物?

1 个答案:

答案 0 :(得分:0)

在考虑了这个之后,我想出了一个解决方案。我们的想法是将$.when()分成两个主要组成部分:插件并加载以前的预订数据。首先,我构建了一个$.when()构造来加载插件。

$.when( # load plugins
    buildJstree(), buildCalendar()
).fail( # Handle failed plugins
    () -> # Code to handle failed plugin.
)

现在,如果其中一个插件失败,那么执行将停止,我可以处理该失败的插件。

如果所有插件加载成功,那么我可以加载我的预订并继续,所以我有:

$.when( # Load plugins.
    buildJstree(), buildCalendar()
).fail(
    () -> # Code to handle failed plugin.
).then( # Load previous booking data.
    () ->
        # If it's a new booking, don't need to load previous data.
        return if id is null

        # Editing an existing booking
        getBookingDetails(id)
        .then(
            (bookingResponse) =>
                # ... populate form with data from bookingResponse ...
                $("#name").val(bookingResponse[...])
                # etc., Rest is omitted
        )
)

所以现在我有了一个流水线方法,加载插件,然后加载数据,然后填充表单。

我也不需要拒绝Deferred对象作为我预期控制流的一部分,因为我提前检查了一个空字符串。事后看来,我原本可以在我的初始代码中完成此操作。