LEARNING JAVASCRIPT - Trang 237

consequences, which is why async exists. Wouldn’t it be nice if you could have the

performance benefits of async without the additional conceptual difficulty? That’s

where generators can help us.
Consider the “callback hell” example we used previously: reading three files, delaying

for one minute, then writing the contents of the first three files out to a fourth file.

How our human minds would like to write this is something like this pseudocode:

dataA = read contents of 'a.txt'
dataB = read contents of 'b.txt'
dataC = read contents of 'c.txt'
wait 60 seconds
write dataA + dataB + dataC to 'd.txt'

Generators enable us to write code that looks very much like this…but the function‐

ality doesn’t come out of the box: we’ll have to do a little work first.
The first thing we need is a way to turn Node’s error-first callbacks into promises.

We’ll encapsulate that into a function called

nfcall

(Node function call):

function

nfcall

(

f

,

...

args

) {

return

new

Promise

(

function

(

resolve

,

reject

) {

f

.

call

(

null

,

...

args

,

function

(

err

,

...

args

) {

if

(

err

)

return

reject

(

err

);

resolve

(

args

.

length

<

2

?

args

[

0

]

:

args

);

});
});
}

This function is named after (and based on) the nfcall method in

the

Q promise library

. If you need this functionality, you should

probably use Q. It includes not only this method, but many more

helpful promise-related methods as well. I present an implementa‐

tion of nfcall here to demonstrate that there is no “magic.”

Now we can convert any Node-style method that takes a callback to a promise. We’ll

also need

setTimeout

, which takes a callback…but because it predates Node, it wasn’t

hip to the error-first convention. So we’ll create

ptimeout

(promise timeout):

function

ptimeout

(

delay

) {

return

new

Promise

(

function

(

resolve

,

reject

) {

setTimeout

(

resolve

,

delay

);

});
}

The next thing we’ll need is a generator runner. Recall that generators are not inher‐

ently asynchronous. But because generators allow the function to communicate to the

caller, we can create a function that will manage that communication—and know

how to handle asynchronous calls. We’ll create a function called

grun

(generator run):

Generators | 213

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.