【问题标题】:How to return value from an async call如何从异步调用中返回值
【发布时间】:2012-03-13 04:00:47
【问题描述】:

我在coffeescript中有以下功能:

newEdge: (fromVertexID, toVertexID) ->
    edgeID = this.NOID
    @client.methodCall('ubigraph.new_edge', [fromVertexID, toVertexID], (error, value) ->
        if(error)
            console.log('ubigraph.new_edge error: ' + error)
        edgeID = value
    )
    edgeID

@client.methodCall 指的是 xmlrpc 库。 我的问题是如何将值作为 edgeID 返回。我是否为此使用回调?

如果是这样,回调应该如下所示:?

# callback is passed the following parameters:
# 1. error - an error, if one occurs
# 2. edgeID - the value of the returned edge id
newEdge: (fromVertexID, toVertexID, callback) ->
    @client.methodCall('ubigraph.new_edge', [fromVertexID, toVertexID], (error, value) ->
        if(error)
            console.log('ubigraph.new_edge error: ' + error)
        edgeID = value
        callback(error, value)
    )

【问题讨论】:

    标签: node.js callback coffeescript


    【解决方案1】:

    是的,回调是异步调用的常用解决方案,有时你有回调调用回调调用回调,回调一直向下。不过,我可能会做一些不同的事情:

    newEdge: (fromVertexID, toVertexID, on_success = ->, on_error = ->) ->
        @client.methodCall('ubigraph.new_edge', [fromVertexID, toVertexID], (error, edge_id) ->
            if(error)
                console.log('ubigraph.new_edge error: ' + error)
                on_error(error)
            else
                on_success(edge_id)
        )
    

    主要的区别是我的有单独的成功和错误回调,以便调用者可以分别处理这些条件,不同条件的单独回调是一种常见的方法,因此大多数人应该熟悉。我还添加了默认的无操作回调,以便回调是可选的,但主要方法体可以假装它们一直被提供。

    如果您不喜欢使用四个参数,那么您可以为回调使用“命名”参数:

    newEdge: (fromVertexID, toVertexID, callbacks = { }) ->
        @client.methodCall('ubigraph.new_edge', [fromVertexID, toVertexID], (error, edge_id) ->
            if(error)
                console.log('ubigraph.new_edge error: ' + error)
                callbacks.error?(error)
            else
                callbacks.success?(edge_id)
        )
    

    对回调使用对象/散列可以让您使用 existential operator 而不是 no-ops 来使回调可选。


    Aaron Dufour 指出单个回调是 Node.js 中的常用模式,因此您的原始方法更适合 node.js:

    newEdge: (fromVertexID, toVertexID, callback = ->) ->
        @client.methodCall('ubigraph.new_edge', [fromVertexID, toVertexID], (error, edge_id) ->
            if(error)
                console.log('ubigraph.new_edge error: ' + error)
            callback(error, edge_id)
        )
    

    【讨论】:

    • 即使有一个回调,函数的用户也可以决定在每种情况下要做什么,但基本上,你的答案是:回调是这样做的方式。是我要找的那个。谢谢
    • @lowerkey:确实如此,但单独的回调似乎是通常的方法; jQuery 至少对成功和错误条件使用单独的回调,因此大多数人都会熟悉它。我已经(试图)澄清这一点。
    • 大多数 node.js 库都使用单个回调,并将错误作为第一个参数,这允许它们彼此相当无缝地对话。我建议在单独的回调中采用这种方式。
    • @AaronDufour:如果单个回调是 node.js 中的常用方法,那么您是对的,最好使用单个回调来保持一致性。
    • 我想指出你可以在没有参数的情况下也可以在使用fn? argsfn?() 的函数上使用existential operators。 CoffeeScript 会将其编译成类似if (typeof fn === "function") fn(args).
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    相关资源
    最近更新 更多