2013-05-16 2 views
0

У меня есть функция, вызывающая две асинхронные функции. Основная функция обрабатывает запросы от пользователей. Вот пример:Как выполнить две операции async за один шаг в node.js как одну атомную операцию?

mainFunction(req, res, done) { 
    asyncExist(req, function(exists) { 
     if (!exists) { 
      asyncCreate(req, done); 
     } 
    }) 
} 

Проблема в том, что у меня много запросов. Моя основная функция - вызов async. Nodejs выполняет функцию asyncExist для многих запросов перед вызовом функции asyncCreate. В результате функция asyncCreate вызывает много раз с теми же параметрами. Вопрос в том, что делать с этой фундаментальной проблемой?

+0

Я не вижу проблемы. Функции всегда будут вызываться с правильными параметрами один раз. – TheHippo

+0

Пожалуйста, обратите внимание на то, что я говорю о нескольких запросах. – hsd

+0

node.js однопоточный, поэтому данные не смешиваются. Один запрос за время обрабатывается, контекст переключается всякий раз, когда происходит обратный вызов или «возвращается». – TheHippo

ответ

0

Вам нужен механизм блокировки. Я не уверен, какой datastore вы используете, но вам нужно выяснить, какие блокировки или примитивы транзакций он предоставляет.

Блокировка хранилища данных позволяет разрешить первый запрос сделать последующие запросы до того, как они начнутся с asyncExist, пока первый запрос не будет полностью завершен.

Я использовал lock pattern for redis, который выглядел так:

mainFunction(req, res, done) { 
    asyncGetLock(function(releaseLock) { 
    asyncExist(req, function(exists) { 
     if(exists) { 
     releaseLock(); 
     return; 
     } 
     asyncCreate(req, done, function() { 
     releaseLock(); 
     }); 
    }); 
    }); 
} 

Аналогичная концепция применяется, если вы используете другие датасторы. Например, в SQL он будет называться транзакцией. Ваш первый запрос будет begin transaction, тогда вы сделаете свой тест и свое условное обновление, а затем вы получите commit или rollback в качестве последнего шага.

+0

Это может быть решением для меня. Я использую mongodb. Вопрос о том, как использовать блокировку для этой БД? – hsd

0

Вы можете исследовать с помощью обещаний (например, when), если вам нужно что-то сделать после завершения нескольких асинхронных вызовов.

См http://blog.jcoglan.com/2013/03/30/callbacks-are-imperative-promises-are-functional-nodes-biggest-missed-opportunity/ для получения дополнительной информации о обещаниях ...

+0

Это то, что не решает проблему. Аналогичные вещи находятся в асинхронной библиотеке или шаге, но это не решение. – hsd

Смежные вопросы