2013-05-19 4 views
0

У меня небольшая проблема с функцией в классе моего узла nodejs/express.Как преобразовать функцию в функцию async.each

У меня есть следующие функции:

@resolveServers = (url, servers, resolved) -> 
    result = [] 
    treatServer(url, server, (serverObject) -> 
    result.push serverObject 
    resolved result if result.length is servers.length 
) for server in servers 

И поскольку функция лакомство сервер может принять дикий, и, как намекнул на эту question мой, я рассматривал, используя async каждый для этого.

Так что я здесь:

@resolveServers = (url, servers, resolved) -> 
    result = [] 
    async.each(servers, treatServer(url, server, (serverObject) -> 
    result.push serverObject 
     resolved result if result.length is servers.length 
), (err) -> 
    if err 
     console.log next err 
) 

И я в настоящее время получаю следующее сообщение об ошибке:

ReferenceError: server is not defined 

Функция treatServer нуждается в URL-адрес и сервер для массива серверов. Но я не знаю, как получить этот экземпляр сервера для каждого из них и передать его функции treatServer.

Любая идея о том, что я делаю неправильно?

Спасибо.

Обновление: Я немного разочарован, так как у меня нет никакой выгоды при использовании async. Используемая функция занимает приблизительно 6500 мс, а асинхронная - одна и та же. Я думаю, каждая функция из coffeescript действительно хорошо работает.

Обновление: После дополнительных испытаний я выясню, что функция работает медленнее с асинхронным использованием. Действительно странно.

ответ

4

I подумайте, что вы хотите: async.map: он собирает результаты всех операций и передает их как массив для окончательного обратного вызова. Он также поддерживает порядок входного массива, который async.each не делает (но это может и не быть проблемой).

@resolveServers = (url, servers, resolved) -> 
    async.map(servers, (server, callback) -> 
    treatServer(url, server, (serverObject) -> 
     callback null, serverObject 
    ) 
    , (err, result) -> 
    if err 
     console.log next err 
    resolved err, result // see text 
) 

Поскольку мой CF не столь велик, версия JS тоже:

function resolveServers(url, servers, resolved) { 
    async.map(servers, function(server, callback) { 
    treatServer(url, server, function(serverObject) { 
     callback(null, serverObject); 
    }); 
    }, function(err, result) { 
    if (err) 
     console.log(err); 
    resolved(err, result); 
    }); 
} 

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

2

Функция итераторная async.each принимает два параметра, как это:

async.each(openFiles, 
    function(file, callback) { 
    // do something with file 
    callback() 
    }, function(err){ 
    // if any of the saves produced an error, err would equal that error 
}); 

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

@resolveServers = (url, servers, resolved) -> 
    result = [] 
    async.each(servers, (server, callback) -> 
    treatServer(url, server, (serverObject) -> 
     result.push serverObject 
     resolved result if result.length is servers.length 
     callback() 
    ) 
    , (err) -> 
    if err 
     console.log next err 
) 
Смежные вопросы