LEARNING JAVASCRIPT - Trang 238

function

grun

(

g

) {

const

it

=

g

();

(

function

iterate

(

val

) {

const

x

=

it

.

next

(

val

);

if

(

!

x

.

done

) {

if

(

x

.

value

instanceof

Promise

) {

x

.

value

.

then

(

iterate

).

catch

(

err

=>

it

.

throw

(

err

));

}

else

{

setTimeout

(

iterate

,

0

,

x

.

value

);

}
}
})();
}

grun

is based heavily on runGenerator, presented in Kyle Simpson’s

excellent

series of articles on generators

. I highly recommend that

you read those articles as a supplement to this text.

This is a very modest recursive generator runner. You pass it a generator function,

and it runs it. As you learned in

Chapter 6

, generators that call

yield

will pause until

next

is called on their iterator. This function does so recursively. If the iterator

returns a promise, it waits for the promise to be fulfilled before resuming the iterator.

On the other hand, if the iterator returns a simple value, it immediately resumes the

iteration. You may be wondering why we call

setTimeout

instead of just calling

iterate

directly; the reason is that we gain a little efficiency by avoiding synchronous

recursion (asynchronous recursion allows the JavaScript engine to free resources

more quickly).
You may be thinking “This is a lot of fuss!” and “This is supposed to simplify my life?”,

but the hard part is over.

nfcall

allows us to adopt the past (Node error-first callback

functions) to the present (promises), and

grun

allows us access to the future today

(expected in ES7 is the

await

keyword, which will essentially function as

grun

, with

an even more natural syntax). So now that we’ve got the hard part out of the way, let’s

see how all of this makes our life easier.
Remember our “wouldn’t it be nice” pseudocode from earlier in this chapter? Now we

can realize that:

function*

theFutureIsNow

() {

const

dataA

=

yield

nfcall

(

fs

.

readFile

,

'a.txt'

);

const

dataB

=

yield

nfcall

(

fs

.

readFile

,

'b.txt'

);

const

dataC

=

yield

nfcall

(

fs

.

readFile

,

'c.txt'

);

yield

ptimeout

(

60

*

1000

);

yield

nfcall

(

fs

.

writeFile

,

'd.txt'

,

dataA

+

dataB

+

dataC

);

}

214 | Chapter 14: Asynchronous Programming

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.