node.js中的流发生了什么顺序

时间:2014-09-24 15:05:47

标签: node.js stream couchdb couchdb-nano

我试图了解node.js流中发生的顺序。我正在运行的脚本采用一组名称/电子邮件对,在该集合上运行,为每个创建一个couchdb条目,然后生成一个QR代码并将其插入该couchdb条目中。

以下是代码:

/*
 * This script takes a collection of names/emails and creates tickets for them.
 */

// Connect to Couch.
var db = require('nano')('https://' + process.env.USER + ':' + process.env.PASS + '@' + process.env.COUCH);

// Load QR Generator.
var qr = require('qr-image');

// Who to email?
var people = [
  { name: 'Katie', email: 'katie@*****.com' },
  { name: 'Alex', email: 'alex@*****.com' },
  { name: 'Kelsey', email: 'kelsey@*****.com' }
];

var tix = 0;

// For Each preson in the above list,
people.forEach(function (person, index, array) {

  // (1) assemble a grit-ticket doc for couch,
  var ticket = {
    "name": person.name,
    "email": person.email,
    "purchaser": "complimentary",
    "type": "ticket"
  };

  // (2) insert that doc into CouchDB,
  db.insert(ticket, function (error, doc, headers) {
    if (error) return console.log("Couch Error: ", error, "Headers: ", headers);

    // (3)  make a QR code,
    var code = qr.image('https://tedxgramercy.com/attendee?id=' + doc.id, { type: 'png' });

    // (4) add that QR code to the doc,
    code.pipe( db.attachment.insert(doc.id, 'qr-code.png', null, 'image/png', { rev: doc.rev }, function (err, reply) {
      if (err) { return console.log("Couch image error: ", err) }
      console.log("Couch image reply: ", reply);
    }) );
    code.on('end', function (error) {
      if (error) { return console.log('QR Submition', [error]) }
      tix += 1;

      // (5) Report out success.
      console.log(tix + " tickets created successfully.");

    });

  });

});

当我运行此脚本(有6封电子邮件,而不仅仅是3封)时,我得到的是:

$ node makeTix.js 
1 tickets created successfully.
2 tickets created successfully.
3 tickets created successfully.
4 tickets created successfully.
5 tickets created successfully.
Couch image reply:  { ok: true,
  id: '8e15d0676ec8d9f686ebbd38237a',
  rev: '2-f03610b92d3461fc9c167f2405e7a2d0' }
6 tickets created successfully.
Couch image reply:  { ok: true,
  id: '8e15d0676ec8d9f8f686ebbd3823806e',
  rev: '2-eb0f676e4ed6f7203420a4864357e3f8' }
Couch image reply:  { ok: true,
  id: '8e15d0676ec8d9f8f686ebbd38236158',
  rev: '2-038c68f6d57b1925c0353fca3b2d59c1' }
Couch image reply:  { ok: true,
  id: '8e15d0676ec8d9f8f686ebbd382364a7',
  rev: '2-9a19a3cd4b8cff2ae2b38cf000dd0aaf' }
Couch image reply:  { ok: true,
  id: '8e15d0676ec8d9f8f686ebbd38236fb4',
  rev: '2-40c0ccc77c07f470424958e6d6e88a9b' }
Couch image reply:  { ok: true,
  id: '8e15d0676ec8d9f8f686ebbd38236174',
  rev: '2-ac78e326b9898d4a340228faa63167e1' }

我试图理解的是为什么我以这种半交错的顺序获取日志,而不是一个" Couch图像回复"然后成功创建了一张"#票。"

任何帮助都会摇滚!

更新啊,我正在学习:)好的,所有forEach函数都会立刻触发。去节点!那太荒谬了。好的,还有一个问题......

如何成功发布"#票据"如果图像插入没有错误回复,则仅记录火灾?我可以将code.on(' end')放在couchdb回调中吗?不,不,管道内的那些会让人感到非常困惑....我有点迷失。

1 个答案:

答案 0 :(得分:2)

Node.js是异步的,这就是你看到这种行为的原因,流与此无关。 (信息来自MatthewBakaitis的流部分)。

每个回调(或者我应该说,每个异步函数)基本上都是"嘿,计算机,这样做并在你完成时给我打电话#34;,以便一切都在同一时间发生(来自用户视图) 。 ForEach也是异步的,db.insert也是如此,所以代码中发生的事情基本上是:

//For each people, send a request to the computer to do that function
people.forEach(function (person, index, array) {
//Synchronous part, then
//Hey, send this data to the db for me, and call me when you re done
db.insert(ticket, function (error, doc, headers) {
//Once data is inserted
//Synchronous part
//When pipe happen, do this
code.pipe
//When finished, do this
code.on('end'

所以六个人,发生的事情是:

forEach start function for people 1
forEach start function for people 2
forEach start function for people 3
forEach start function for people 4
forEach start function for people 5
In the meantime, function has ended for 1, so execute the callback
forEach start function for people 1
function has ended for 2, so execute the callback
function has ended for 3, so execute the callback
function has ended for 4, so execute the callback
function has ended for 5, so execute the callback
function has ended for 6, so execute the callback

有点难以理解,你只需要接受eveything将在同一时间完成。

更新:

虽然每个都是异步的,它会锁定"在让代码继续之前发生在内部的代码,所以:

forEach(function (element) {
    //Asynchronous code and calculing tx
});
console.log(tx + ' ticket created successfully);

应该这样做。