Ver código fonte

[chunkedForEach]: add timeout fallback

mightyplow 7 anos atrás
pai
commit
43039024c4
1 arquivos alterados com 26 adições e 11 exclusões
  1. 26 11
      src/array/chunkedForEach.js

+ 26 - 11
src/array/chunkedForEach.js

@@ -1,21 +1,39 @@
 import checkArray from './_checkArray';
 
-const $postMessage = typeof postMessage !== 'undefined' && postMessage;
+const processViaPostMessage = (ar, fn, resolve, chunkSize, msg) => {
+    const values = [...ar];
 
-const mkExecNextMessage = (values, fn, resolve, chunkSize, msg) => function execNext ({ data }) {
-    if (data !== msg) { return; }
+    window.addEventListener('message', execNext);
+    postMessage(msg, '*');
 
-    if (values.length) {
-        values.splice(0, chunkSize).forEach(fn);
-        $postMessage(msg, '*');
+    function execNext ({ data }) {
+        if (data !== msg) { return; }
+
+        if (values.length) {
+            values.splice(0, chunkSize).forEach(fn);
+            postMessage(msg, '*');
+        } else {
+            resolve();
+            window.removeEventListener('message', execNext);
+        }
+    }
+};
+
+const processViaTimeout = (ar, fn, resolve, chunkSize, msg) => {
+    if (ar.length) {
+        ar.slice(0, chunkSize).forEach(fn);
+        setTimeout(processViaTimeout.bind(this, ar.slice(chunkSize), fn, resolve, chunkSize, msg));
     } else {
         resolve();
-        window.removeEventListener('message', execNext);
     }
 };
 
 const createSplitMessage = () => `FOR_EACH_SPLIT_${Math.floor(Math.random() * 10000)}`;
 
+const process = typeof postMessage === 'undefined'
+    ? processViaPostMessage
+    : processViaTimeout;
+
 /**
  * Splits an array into chunks and breaks the execution queue to ensure reactivity.
  *
@@ -27,12 +45,9 @@ const createSplitMessage = () => `FOR_EACH_SPLIT_${Math.floor(Math.random() * 10
  */
 const chunkedForEach = (ar = [], fn = Function.prototype, chunkSize = 1) => {
     checkArray(ar);
-    if (!$postMessage) { throw Error('postMessage not available'); }
 
     return new Promise((resolve, reject) => {
-        const streamMessage = createSplitMessage();
-        window.addEventListener('message', mkExecNextMessage([...ar], fn, resolve, chunkSize, streamMessage));
-        $postMessage(streamMessage, '*');
+        process(ar, fn, resolve, chunkSize, createSplitMessage());
     });
 };