JS Q承诺不会传播错误



我正在使用https://github.com/kriskowal/q创建一组(深度)嵌套的承诺。错误并没有像我预期的那样传播到最外面的.catch()。请参阅我的咖啡脚本中的html = tmpl_func(data_)行:

$exp.setEventResponse = (event_str, pre_func, tmpl_list, post_func) ->
    $(document).on(event_str, (_event, args) ->
        console.log("on: #{event_str}. #{args}")
        data = args or {}
        data._start_ts = now = Date.now()
        data.trigger = $exp.trigger
        #return data
        p = Q(data)
        if pre_func
            p = p.then( (data_) ->
                pre_func(data_)
            ).then( (data_) ->
                if data_._start_ts != now
                    throw new Error("#{event_str}_pre must return data or Q(...).then(() -> data)")
                return data_
            )
        p.then( (data_) ->
            pp = Q(data_)
            if tmpl_list or data_.extraTmpl_list
                console.log(tmpl_list.concat(data_.extraTmpl_list or []))
                for tmpl_args in tmpl_list.concat(data_.extraTmpl_list or [])
                    closure_func = (ppp, tmpl_args) ->
                        return ppp.then((data_) ->
                            if tmpl_args.length == 3
                                [selector, tmpl_func, replace] = tmpl_args
                            else
                                [selector, tmpl_func] = tmpl_args
                                replace = true
                            try
                                html = tmpl_func(data_)
                            catch error
                                console.log error
                                throw error
                            if replace
                                $(selector).replaceWith(html)
                            else
                                $(selector).html(html)
                            return data_
                        )
                    pp = closure_func(pp, tmpl_args)
                pp = pp.then( (data_) ->
                    if data_._start_ts != now
                        throw new Error("#{event_str}_tmpl must return data or Q(...).then(() -> data)")
                    return data_
                )
            return pp
        )

        if post_func
            p = p.then( (data_) ->
                post_func(data_)
            ).then( (data_) ->
                if data_._start_ts != now
                    throw new Error("#{event_str}_post must return data or Q(...).then(() -> data)")
                return data_
            )
        p.then( (data_) ->
            data_._end_ts = Date.now()
            duration_sec = (data_._end_ts - data_._start_ts) / 1000.0
            if duration_sec >= _durationLogThreshold_sec
                console.log("Event #{event_str} duration: #{duration_sec} sec")
            return data_
        ).catch( (reason) ->
            console.log(reason)
            #alert(reason)
        ).done()
    )

这样调用:

$exp.setEventResponse('showScan', 
   showScan_pre, [['#content', showScan_tmpl]], showScan_post)

如果tmpl_func引发错误,它不会在代码段末尾附近触发.catch( (reason) ->。我希望能够处理closure_func内部发生的任何错误(例如,如果在将脚本发送到replaceWith时,运行html中的脚本标记触发的脚本时出现错误)。

我是否正确使用了承诺?

如何正确处理嵌套承诺中的错误?

我是否误解了catch应该发生的事情?

您缺少对p:的重新分配

p.then( (data_) ->
    pp = Q(data_)
    …
    return pp
)

应该需要

p = p.then( (data_) ->
    pp = Q(data_)
    …
    return pp
)

否则,您只是分支链,但在pre_func之后执行post_func

最新更新