2014-10-24 12 views
1

Я пытаюсь создать api из серверов braintree. Ссылаясь на этот документ https://developers.braintreepayments.com/javascript+node/reference/general/result-handling/search-resultsNodejs stream (Ошибка: не удается установить заголовки после их отправки)

Чтобы получить доступ ко всем транзакциям со своего сервера, я должен вернуть поток узлов.

экс

app.get('/project', function(req, res) { 
    if(req.user) { 

     var stream = gateway.transaction.search(function (search) { 
     search.customerId().is(req.user.id); 
     }); 

     stream.on("ready", function() { 
     console.log(stream.searchResponse); 
     }); 

     stream.on("data", function (data) { 
     res.json(data) // can't set headers after they are sent. 
     }); 

    } 
}); 

Я понимаю возвращает поток данных в куски, так что выше res.json(), скорее всего, вызывается несколько раз приводит к Error: Can't set headers after they are sent.

Итак, мой вопрос в том, как я могу отправить эти данные клиенту в один кусок? Потоки nodejs меня сбивают с толку, я собираюсь больше узнать об этом, но было бы прекрасно понять, как отправить данные клиенту без повторной отправки заголовков.

+0

'res.json()' предназначен для использования как один отклик и заканчивается t он ответил. Он не может быть вызван более одного раза с тем же запросом/ответом. Он также, как правило, не может использоваться на произвольных фрагментах данных, поскольку для получения юридического JSON требуется полностью сформированная часть данных javascript. – jfriend00

+0

Да, я получаю это до степени, но мой вопрос заключается в том, как я беру эти данные внутри, '.on ('data')' callback и отправлять эти данные клиенту. Может быть, я должен улучшить свои навыки работы с javascript и создать функцию из обратного вызова или что-то, а затем использовать 'res.json()' внутри потока '.on ('end')' callback? –

+0

Кроме того, вы действительно хотите отправить JSON клиенту или просто хотите передать результаты клиенту? Я не знаю, чего вы на самом деле пытаетесь достичь. – jfriend00

ответ

6

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

То, что вы, вероятно, хотите что-то вроде этого вместо (предполагается, что stream не в режиме объекта):

app.get('/project', function(req, res) { 
    if(req.user) { 

     var stream = gateway.transaction.search(function (search) { 
     search.customerId().is(req.user.id); 
     }); 

     stream.on("ready", function() { 
     console.log(stream.searchResponse); 
     }); 

     var buf = ''; 
     stream.on("data", function (data) { 
     buf += data; 
     }); 

     stream.on("end", function() { 
     res.setHeader('Content-Type', 'application/json'); 
     res.send(buf); 
     }); 

    } 
}); 

Или просто труба поток в ответ:

app.get('/project', function(req, res) { 
    if(req.user) { 

     var stream = gateway.transaction.search(function (search) { 
     search.customerId().is(req.user.id); 
     }); 

     stream.on("ready", function() { 
     console.log(stream.searchResponse); 
     }); 

     res.setHeader('Content-Type', 'application/json'); 

     stream.pipe(res); 
    } 
}); 

Для потока объекта вы можете сделать:

app.get('/project', function(req, res) { 
    if(req.user) { 

     var stream = gateway.transaction.search(function (search) { 
     search.customerId().is(req.user.id); 
     }); 

     stream.on("ready", function() { 
     console.log(stream.searchResponse); 
     }); 

     var result = []; 
     stream.on("data", function (data) { 
     result.push(data); 
     }); 

     stream.on("end", function() { 
     res.json(result); 
     }); 

    } 
}); 
+0

Отличный материал, я продолжаю видеть трубы, но это действительно помогает помещать его в контекст.Это имеет смысл, позвольте мне попробовать. –

+0

Первый метод, похоже, сработал, второй метод я получил ошибку. Мне нравится первый метод, но я получаю '[object Object] [object Object]', поэтому очевидно, что на сервере braintree есть два объекта (транзакции). Итак, как мне вернуть их в виде массива объектов, а не '[object Object] [object Object]', который задает такой вопрос noob, но мой javascript для ванилин может использовать некоторую работу. –

+0

Я воспроизвел то, что происходит здесь http://jsfiddle.net/b30c7ady/ Я думаю, что это очень похоже на то, что происходит. Возможно, мне придется открыть новый вопрос специально для этого, но я хотел бы знать, почему я получаю '[object Object]'. По крайней мере, я могу возиться со скрипкой, и мне не нужно беспокоиться о перезапуске моего сервера снова и снова и повторной регистрации, так что это хорошо. –

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