Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.18 KB | None | 0 0
  1. class FunctifiedAsync {
  2. constructor(iterable) {
  3. this.iterable = iterable;
  4. }
  5.  
  6. async *[Symbol.asyncIterator]() {
  7. for await (const value of this.iterable) {
  8. yield value;
  9. }
  10. }
  11.  
  12. map(callback) {
  13. const iterable = this.iterable;
  14. return FunctifiedAsync.fromGenerator(async function* () {
  15. for await (const value of iterable) {
  16. yield callback(value);
  17. }
  18. });
  19. }
  20.  
  21.  
  22. skipWhile(predicate) {
  23. const iterable = this.iterable;
  24. return FunctifiedAsync.fromGenerator(async function* () {
  25. let skip = true;
  26. for await (const value of iterable) {
  27. if (!predicate(value)) {
  28. skip = false;
  29. }
  30. if (!skip) {
  31. yield value;
  32. }
  33. }
  34. });
  35. }
  36.  
  37. flatten() {
  38. const iterable = this.iterable;
  39. return FunctifiedAsync.fromGenerator(async function* () {
  40. for await (const value of iterable) {
  41. if (value[Symbol.iterator] || value[Symbol.asyncIterator]) {
  42. yield* new FunctifiedAsync(value);
  43. } else {
  44. yield value;
  45. }
  46. }
  47. });
  48. }
  49.  
  50. takeUntil(predicate) {
  51. const iterator = this.iterable[Symbol.asyncIterator]();
  52. const self = this;
  53. return FunctifiedAsync.fromGenerator(async function* () {
  54. if (self.hasOwnProperty("startValue")) {
  55. yield self.startValue;
  56. }
  57. while (true) {
  58. const result = await iterator.next();
  59. if (result.done) {
  60. break;
  61. } else {
  62. if (predicate(result.value)) {
  63. // save the value so we can yield if takeUntil is called again
  64. self.startValue = result.value;
  65. break;
  66. } else {
  67. yield result.value;
  68. }
  69. }
  70. }
  71. });
  72. }
  73.  
  74. static fromGenerator(generator) {
  75. return new FunctifiedAsync({
  76. [Symbol.asyncIterator]: generator
  77. });
  78. }
  79. }
  80.  
  81. const timeoutPromise = timeout => new Promise(resolve => setTimeout(resolve, timeout))
  82.  
  83. // This could be an async API request, but here we just mock the result
  84. const getItemsForPage = (number) => {
  85. console.log(`getting page ${number}`)
  86. return timeoutPromise(1000).then(() => [1, 2, 3, 4].map(x => x + (number * 4)))
  87. }
  88.  
  89. const generateNumbers = function* (n = 0) {
  90. yield n;
  91. const next = n + 1;
  92. // Recurse and delegate to the next generator
  93. yield* generateNumbers(next)
  94. }
  95.  
  96. async function main() {
  97. // Paginate until we find items 7-10.
  98. // Because we're using async iterators, this is lazy. So we won't make
  99. // any requests after we've found our last item (takeUntil).
  100. const asyncIterable = new FunctifiedAsync(generateNumbers())
  101. .map(getItemsForPage)
  102. .flatten()
  103. .skipWhile(x => x < 7)
  104. .takeUntil(x => x > 10)
  105. for await (const x of asyncIterable) {
  106. console.log(x)
  107. }
  108. }
  109.  
  110. main().catch(console.error)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement