LEARNING JAVASCRIPT - Trang 239

It looks a lot better than callback hell, doesn’t it? It’s also neater than promises alone.

It flows the way we think. Running it is simple:

grun

(

theFutureIsNow

);

One Step Forward and Two Steps Back?

You might (quite reasonably) be thinking that we’ve gone to so much trouble to

understand asynchronous execution, then make it easier…and now we’re right back

where we started, except with the extra complication of generators and converting

things to promises and

grun

. And there is some truth in this: in our

theFutureIsNow

function, we have somewhat thrown the baby out with the bathwater. It’s easier to

write, easier to read, and we’re reaping some of the benefits of asynchronous execu‐

tion, but not all of them. The sharp question here is: “Would it be more efficient to

read the three files in parallel?” The answer to that question depends a lot on the

problem, the implementation of your JavaScript engine, your operating system, and

your filesystem. But let’s put aside those complexities for a moment, and recognize

that it doesn’t matter what order we read the three files in, and it’s conceivable that

efficiency would be gained from allowing those file read operations to happen in par‐

allel. And this is where generator runners can lull us into a false sense of compla‐

cency: we wrote the function this way because it seemed easy and straightforward.
The problem (assuming there is a problem) is easy to solve.

Promise

provides a

method called

all

, which resolves when all the promises in an array resolve…and

will execute the asynchronous code in parallel if possible. All we have to do is modify

our function to use

Promise.all

:

function*

theFutureIsNow

() {

const

data

=

yield

Promise

.

all

([

nfcall

(

fs

.

readFile

,

'a.txt'

),

nfcall

(

fs

.

readFile

,

'b.txt'

),

nfcall

(

fs

.

readFile

,

'c.txt'

),

]);

yield

ptimeout

(

60

*

1000

);

yield

nfcall

(

fs

.

writeFile

,

'd.txt'

,

data

[

0

]

+

data

[

1

]

+

data

[

2

]);

}

The promise returned by

Promise.all

provides an array containing the fulfillment

value of each promise in the order they appear in the array. Even though it’s possible

for c.txt to be read before a.txt,

data[0]

will still hold the contents of a.txt, and

data[1]

will still hold the contents of c.txt.

Your takeaway from this section should not be

Promise.all

(though that’s a handy

tool to know about); your takeaway should be to consider what parts of your program

can be run in parallel, and what parts can’t. In this example, it’s even possible that the

timeout could be run in parallel to the file reads: it all depends on the problem you’re

trying to solve. If what’s important is that the three files are read and then 60 seconds

Generators | 215

Liên Kết Chia Sẽ

** Đây là liên kết chia sẻ bới cộng đồng người dùng, chúng tôi không chịu trách nhiệm gì về nội dung của các thông tin này. Nếu có liên kết nào không phù hợp xin hãy báo cho admin.