Как вернуть значение из асинхронного вызова - PullRequest
2 голосов
/ 22 февраля 2012

У меня есть следующая функция в 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)
    )

1 Ответ

3 голосов
/ 22 февраля 2012

Да, обратные вызовы являются обычным решением для асинхронных вызовов, иногда у вас есть обратные вызовы, вызывающие обратные вызовы, вызывающие обратные вызовы, обратные вызовы на всех этапах.Я, вероятно, сделал бы это немного по-другому, хотя:

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)
    )

Основное отличие состоит в том, что у меня есть отдельные обратные вызовы об успешном выполнении и об ошибках, так что вызывающая сторона может обрабатывать эти условия отдельно, обычные обратные вызовы для различных условий являются общимиподход, поэтому он должен быть знаком большинству людей.Я также добавил стандартные обратные вызовы no-op, чтобы обратные вызовы были необязательными, но тело основного метода может делать вид, что они всегда были предоставлены.

Если вам не нравится использовать четыре аргумента, вы можете использовать "named"аргументы для обратных вызовов:

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)
    )

Использование объекта / хеша для обратных вызовов позволяет использовать экзистенциальный оператор вместо no-ops, чтобы сделать обратные вызовы необязательными.


Аарон Дюфур отмечает, что одиночный обратный вызов является обычным шаблоном в 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)
    )
...