Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. # JavaScript Sync/Async forEach
  2. An optionally-asynchronous forEach with an interesting interface.
  3. ## Getting Started
  4. This code should work just fine in Node.js:
  5. First, install the module with: `npm install async-foreach`
  6. ```javascript
  7. var forEach = require('async-foreach').forEach;
  8. forEach(["a", "b", "c"], function(item, index, arr) {
  9. console.log("each", item, index, arr);
  10. });
  11. // logs:
  12. // each a 0 ["a", "b", "c"]
  13. // each b 1 ["a", "b", "c"]
  14. // each c 2 ["a", "b", "c"]
  15. ```
  16. Or in the browser:
  17. ```html
  18. <script src="dist/ba-foreach.min.js"></script>
  19. <script>
  20. forEach(["a", "b", "c"], function(item, index, arr) {
  21. console.log("each", item, index, arr);
  22. });
  23. // logs:
  24. // each a 0 ["a", "b", "c"]
  25. // each b 1 ["a", "b", "c"]
  26. // each c 2 ["a", "b", "c"]
  27. </script>
  28. ```
  29. In the browser, you can attach the forEach method to any object.
  30. ```html
  31. <script>
  32. this.exports = Bocoup.utils;
  33. </script>
  34. <script src="dist/ba-foreach.min.js"></script>
  35. <script>
  36. Bocoup.utils.forEach(["a", "b", "c"], function(item, index, arr) {
  37. console.log("each", item, index, arr);
  38. });
  39. // logs:
  40. // each a 0 ["a", "b", "c"]
  41. // each b 1 ["a", "b", "c"]
  42. // each c 2 ["a", "b", "c"]
  43. </script>
  44. ```
  45. ## The General Idea (Why I thought this was worth sharing)
  46. The idea is to allow the callback to decide _at runtime_ whether the loop will be synchronous or asynchronous. By using `this` in a creative way (in situations where that value isn't already spoken for), an entire control API can be offered without over-complicating function signatures.
  47. ```javascript
  48. forEach(arr, function(item, index) {
  49. // Synchronous.
  50. });
  51. forEach(arr, function(item, index) {
  52. // Only when `this.async` is called does iteration becomes asynchronous. The
  53. // loop won't be continued until the `done` function is executed.
  54. var done = this.async();
  55. // Continue in one second.
  56. setTimeout(done, 1000);
  57. });
  58. forEach(arr, function(item, index) {
  59. // Break out of synchronous iteration early by returning false.
  60. return index !== 1;
  61. });
  62. forEach(arr, function(item, index) {
  63. // Break out of asynchronous iteration early...
  64. var done = this.async();
  65. // ...by passing false to the done function.
  66. setTimeout(function() {
  67. done(index !== 1);
  68. });
  69. });
  70. ```
  71. ## Examples
  72. See the unit tests for more examples.
  73. ```javascript
  74. // Generic "done" callback.
  75. function allDone(notAborted, arr) {
  76. console.log("done", notAborted, arr);
  77. }
  78. // Synchronous.
  79. forEach(["a", "b", "c"], function(item, index, arr) {
  80. console.log("each", item, index, arr);
  81. }, allDone);
  82. // logs:
  83. // each a 0 ["a", "b", "c"]
  84. // each b 1 ["a", "b", "c"]
  85. // each c 2 ["a", "b", "c"]
  86. // done true ["a", "b", "c"]
  87. // Synchronous with early abort.
  88. forEach(["a", "b", "c"], function(item, index, arr) {
  89. console.log("each", item, index, arr);
  90. if (item === "b") { return false; }
  91. }, allDone);
  92. // logs:
  93. // each a 0 ["a", "b", "c"]
  94. // each b 1 ["a", "b", "c"]
  95. // done false ["a", "b", "c"]
  96. // Asynchronous.
  97. forEach(["a", "b", "c"], function(item, index, arr) {
  98. console.log("each", item, index, arr);
  99. var done = this.async();
  100. setTimeout(function() {
  101. done();
  102. }, 500);
  103. }, allDone);
  104. // logs:
  105. // each a 0 ["a", "b", "c"]
  106. // each b 1 ["a", "b", "c"]
  107. // each c 2 ["a", "b", "c"]
  108. // done true ["a", "b", "c"]
  109. // Asynchronous with early abort.
  110. forEach(["a", "b", "c"], function(item, index, arr) {
  111. console.log("each", item, index, arr);
  112. var done = this.async();
  113. setTimeout(function() {
  114. done(item !== "b");
  115. }, 500);
  116. }, allDone);
  117. // logs:
  118. // each a 0 ["a", "b", "c"]
  119. // each b 1 ["a", "b", "c"]
  120. // done false ["a", "b", "c"]
  121. // Not actually asynchronous.
  122. forEach(["a", "b", "c"], function(item, index, arr) {
  123. console.log("each", item, index, arr);
  124. var done = this.async()
  125. done();
  126. }, allDone);
  127. // logs:
  128. // each a 0 ["a", "b", "c"]
  129. // each b 1 ["a", "b", "c"]
  130. // each c 2 ["a", "b", "c"]
  131. // done true ["a", "b", "c"]
  132. // Not actually asynchronous with early abort.
  133. forEach(["a", "b", "c"], function(item, index, arr) {
  134. console.log("each", item, index, arr);
  135. var done = this.async();
  136. done(item !== "b");
  137. }, allDone);
  138. // logs:
  139. // each a 0 ["a", "b", "c"]
  140. // each b 1 ["a", "b", "c"]
  141. // done false ["a", "b", "c"]
  142. ```
  143. ## Contributing
  144. In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt](https://github.com/cowboy/grunt).
  145. _Also, please don't edit files in the "dist" subdirectory as they are generated via grunt. You'll find source code in the "lib" subdirectory!_
  146. ## Release History
  147. 04/29/2013
  148. v0.1.3
  149. Removed hard Node.js version dependency.
  150. 11/17/2011
  151. v0.1.2
  152. Adding sparse array support.
  153. Invalid length properties are now sanitized.
  154. This closes issue #1 (like a boss).
  155. 11/11/2011
  156. v0.1.1
  157. Refactored code to be much simpler. Yay for unit tests!
  158. 11/11/2011
  159. v0.1.0
  160. Initial Release.
  161. ## License
  162. Copyright (c) 2012 "Cowboy" Ben Alman
  163. Licensed under the MIT license.
  164. <http://benalman.com/about/license/>