asFun.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. 'use strict';
  2. const {none, final, isFinal, getFinalValue, many, isMany, getManyValues} = require('../defs');
  3. const next = async (value, fns, index, push) => {
  4. for (let i = index; i <= fns.length; ++i) {
  5. if (value && typeof value.then == 'function') {
  6. // thenable
  7. value = await value;
  8. }
  9. if (value === none) break;
  10. if (isFinal(value)) {
  11. const val = getFinalValue(value);
  12. val !== none && push(val);
  13. break;
  14. }
  15. if (isMany(value)) {
  16. const values = getManyValues(value);
  17. if (i == fns.length) {
  18. values.forEach(val => push(val));
  19. } else {
  20. for (let j = 0; j < values.length; ++j) {
  21. await next(values[j], fns, i, push);
  22. }
  23. }
  24. break;
  25. }
  26. if (value && typeof value.next == 'function') {
  27. // generator
  28. for (;;) {
  29. let data = value.next();
  30. if (data && typeof data.then == 'function') {
  31. data = await data;
  32. }
  33. if (data.done) break;
  34. if (i == fns.length) {
  35. push(data.value);
  36. } else {
  37. await next(data.value, fns, i, push);
  38. }
  39. }
  40. break;
  41. }
  42. if (i == fns.length) {
  43. push(value);
  44. break;
  45. }
  46. value = fns[i](value);
  47. }
  48. };
  49. const nop = () => {};
  50. const asFun = (...fns) => {
  51. fns = fns.filter(fn => fn);
  52. if (!fns.length) return nop;
  53. if (Symbol.asyncIterator && fns[0][Symbol.asyncIterator]) {
  54. fns[0] = fns[0][Symbol.asyncIterator];
  55. } else if (Symbol.iterator && fns[0][Symbol.iterator]) {
  56. fns[0] = fns[0][Symbol.iterator];
  57. }
  58. return async value => {
  59. const results = [];
  60. await next(value, fns, 0, value => results.push(value));
  61. switch (results.length) {
  62. case 0:
  63. return none;
  64. case 1:
  65. return results[0];
  66. }
  67. return many(results);
  68. };
  69. };
  70. asFun.next = next;
  71. asFun.none = none;
  72. asFun.final = final;
  73. asFun.isFinal = isFinal;
  74. asFun.getFinalValue = getFinalValue;
  75. asFun.many = many;
  76. asFun.isMany = isMany;
  77. asFun.getManyValues = getManyValues;
  78. module.exports = asFun;