2013-08-26 4 views
1

Я начал кодирование в Node.js на прошлой неделе. Я написал код для генерации JSON запросов несколько таблиц и not sure if this is correct way of coding asynchronouslyNode.js - Строит JSON асинхронно с несколькими запросами

build_actor(post, function(actor){ 
    build_post_object(post, function(post_object){ 
    build_post_attachments(post, function(attachments){ 
     build_post_comments(post, function(comments){ 
     var post_obj = {}; 
     post_obj.actor = actor; 
     post_obj.object = post_object; 
     post_obj.attachments = attachments; 
     post_obj.comments = comments; 
     console.log(JSON.stringify(post_obj)); // generates JSON 
     }); 
    }); 
    }); 
}); 

function build_actor(post, callback){ 
    //query 
    callback(actor); 
} 
function build_post_object(post, callback){ 
    //query 
    callback(post_object); 
} 
function build_post_attachments(post, callback){ 
    //query 
    callback(attachments); 
} 
function build_post_comments(post, callback){ 
    //query 
    callback(comments); 
} 

Пожалуйста, дайте мне знать, если есть лучший способ для написания нескольких запросов и построения JSON.

+1

Взгляните на асинхронную библиотеку https://github.com/caolan/async. Затем вы можете вызывать все функции аккуратно либо последовательно (если они зависят друг от друга), либо параллельно, а затем ждать завершения всех. Async.parallel, по-видимому, является оружием выбора для вас с помощью метода финиша, который фактически принимает полный результат и что-то делает с ним. – Todilo

+0

Это то, что я хотел :) Спасибо :) –

ответ

1

Я вижу, что у вас уже есть ответ, но я подумал, что я могу увидеть, можно ли сделать изящное решение с использованием async (должно быть меньше кода и/или проще для чтения, чем исходное решение), так же, как и упражнение. И это:

async.series({ 
    actor: async.apply(build_actor, post), 
    post_object: async.apply(build_post_object, post), 
    attachments: async.apply(build_post_attachments, post), 
    comments: async.apply(build_post_comments, post) 
}, 
function (err, result) { 
    console.log(JSON.stringify(result)); 
}); 

Билд _ * - функции должны также обратный вызов нуль (или ошибки) в качестве первого аргумента. Это, как правило, хорошая идея, так как большинство apis и модулей node.js работают таким образом. Например:

function build_actor(post, callback) { 
    // Query 
    callback(null, actor); 
} 

Обратите внимание, что я на самом деле не проверял, но он должен работать.

Итак, магией является то, что async.series может составлять результат как объект, где ключи для результата такие же, как вы назначаете функции. Таким образом, вам не нужно указывать значения объекту, но можете сразу его преобразовать. async.apply - это просто более простой способ вызова функции с уже доступным аргументом. Простой способ будет:

function (callback) { 
    build_actor(post, callback); 
} 

Другим способом было бы переписать свои функции кокетливыми, как это:

function build_actor(post){ 
    return function (callback) { 
    //query 
    callback(null, actor); 
    }; 
} 

И использовать их, как это:

async.series({ actor: build_actor(post) }, ...); 

, который будет еще чище , Также обратите внимание, что если вы можете запускать запросы одновременно, async.parallel будет работать так же хорошо.

+0

Это то, что я написал для актера, actor: function (callback) { build_actor (post, function (actor) { callback (null, actor); }); } Мне пришлось выполнить обратный вызов (null, actor); вместо обратного вызова (актера); и это сработало. Благодаря! Ура! –

+1

Ах да, вы должны были бы это сделать, если не будете следовать соглашению о передаче ошибки в качестве первого аргумента в обратном вызове. Я отредактирую сообщение, чтобы предположить, что функции build_ * изменены на 'callback (null, actor)', чтобы быть более совместимыми с стандартными стандартами узлов. –