Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
201 views
in Technique[技术] by (71.8m points)

node.js - How to 'order' your callbacks without using a blocking structure

I'm new to node.js and stackoverflow and I'm having a little trouble : I want to read two files and do something with them in a specific order. Problem being that i don't know wich one will finish being read first so I don't know how to make sure they will trigger in the right order.

To give an example let's say that I want to read two files and write them in the response :

fs.readFile('./file1',(err,data) => {
    res.write(data);
})
fs.readFile('./file2',(err,data) => {
    res.write(data);
})

How could I make sure the first file will be writen before the second even if the second file is smaller than the first one ?

I could do that :

fs.readFile('./file1',(err,data) => {
    res.write(data);
    fs.readFile('./file2',(err,data) => {
        res.write(data);
    })
})

But it would act like a blocking structure : the second one couldn't start being read before the end of the first one and that's not the point of Node.js... Am I right ?

PS : Sorry if the question is dumb or for my poor english

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One of the reason (out of several) Promise and async/await exists is to solve exactly this kind of issue.

You can create a wrapper to return Promise:

function readSomething(filePath) {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, (err, data) => {
      if (err) reject(err);
      else resolve(data);
    });
}

Then you can call like,

// called in parallel
const result1 = readSomething('./file1');
const result2 = readSomething('./file2');

result1.then((data) => {
  res.write(data) // or anything
  // to order, chaining promise
  return result2;
})
.then(data => res.write(data))

With async/await you can do (await is valid only inside async function):

async function handleResults() {
  res.write(await result1)
  res.write(await result2)
}

Note: Watch out for error (reject cases). They become a little tricky in this situation. (I'm you can figure it out)

In nodejs you can utilise the power of EventEmitter as well. You can also check out reactive programming implemented by rxjs library for Observer pattern.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...