{"id":21530960,"url":"https://github.com/ibrahimtanyalcin/taskq","last_synced_at":"2025-04-10T00:16:47.366Z","repository":{"id":57117319,"uuid":"108156384","full_name":"IbrahimTanyalcin/taskq","owner":"IbrahimTanyalcin","description":"Async module loader with declerative dependency management in HTML and compatibility with ES6 import/export","archived":false,"fork":false,"pushed_at":"2020-03-22T00:08:34.000Z","size":156,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T00:16:40.290Z","etag":null,"topics":["async-modules","es5","es5-javascript","es6","html5","javascript","javascript-library","module-loader","module-pattern","promises","queue","script-loader","task-manager","task-runner","umd-modules"],"latest_commit_sha":null,"homepage":"http://taskq.ibrahimtanyalcin.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IbrahimTanyalcin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-24T16:49:37.000Z","updated_at":"2024-08-07T17:53:40.000Z","dependencies_parsed_at":"2022-08-23T04:40:33.697Z","dependency_job_id":null,"html_url":"https://github.com/IbrahimTanyalcin/taskq","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IbrahimTanyalcin%2Ftaskq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IbrahimTanyalcin%2Ftaskq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IbrahimTanyalcin%2Ftaskq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IbrahimTanyalcin%2Ftaskq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IbrahimTanyalcin","download_url":"https://codeload.github.com/IbrahimTanyalcin/taskq/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248131318,"owners_count":21052820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async-modules","es5","es5-javascript","es6","html5","javascript","javascript-library","module-loader","module-pattern","promises","queue","script-loader","task-manager","task-runner","umd-modules"],"created_at":"2024-11-24T02:10:59.516Z","updated_at":"2025-04-10T00:16:47.342Z","avatar_url":"https://github.com/IbrahimTanyalcin.png","language":"JavaScript","readme":"# taskq\n\n[![Build Status](https://travis-ci.org/IbrahimTanyalcin/taskq.svg?branch=master)](https://travis-ci.org/IbrahimTanyalcin/taskq)\n\u003ca href=\"https://www.patreon.com/ibrahimTanyalcin\" title=\"Patreon donate\"\u003e\u003cimg src=\"https://img.shields.io/badge/patreon-donate-yellow.svg\" alt=\"Patreon donate\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://www.codacy.com/app/IbrahimTanyalcin/taskq?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=IbrahimTanyalcin/taskq\u0026amp;utm_campaign=Badge_Grade\" title=\"Codacy\"\u003e\u003cimg src=\"https://api.codacy.com/project/badge/Grade/06f045df886848f09519df15388c8bf6\" alt=\"Codacy Badge\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/@ibowankenobi/taskq\" title=\"Npm\"\u003e\u003cimg src=\"https://badge.fury.io/js/%40ibowankenobi%2Ftaskq.svg\" alt=\"Npm Badge\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://zenodo.org/badge/latestdoi/108156384\"\u003e\u003cimg src=\"https://zenodo.org/badge/108156384.svg\" alt=\"DOI\"\u003e\u003c/a\u003e\n\n\u003chr\u003e\n\n# Async Modules Supporting ES5 \u0026 ES6 with Control Flow\n\n## ⇩ First, your 1 min cheatsheet ⇩\n![cheatsheet](./cheatsheet.png)\n\n\u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/6/6a/Detail_der_Rechenmaschine_von_Johann_Helfrich_M%C3%BCller.jpg\" width=\"100%\"\u003e\u003c/img\u003e\n\n# Navigation\n\nIf you want you can jump straight into the [**examples**](#examples-).\n\n- ## [Advantages](#advantages-) \n- ## [API](#api-)\n- ## [Reading](#reading-)\n- ## [What does it do?](#what-does-it-do-)\n- ## [Usage](#usage-)\n- ## [Changelog](#changelog-)\n- ## [Examples](#examples-)\n\n## Advantages [⏎](#advantages)\n\n- \u003cspan style=\"font-size:200%;\"\u003e0\u003c/span\u003e dependencies\n- No polyfill required\n- No transpiling required.\n- No config file etc.\n- About 6kB when minimized\n- Will work on ie9+.\n- Will play nice with other technologies/patterns you use in your page\n- Non-render blocking\n- You can pause/resume the main thread\n- Aware of document state (hidden, minimized etc.)\n- Fine grained control on execution of all imported scripts.\n- Uses Promises combined with requestAnimationFrame(rAF). Falls back to rAF on older browsers (ie etc).\n- Supports nested/single dynamic imports. Your main thread will wait until a module finishes dynamically importing other modules.\n- Supports *then* , *catch* phrases for dynamic imports. \n- You can do things that you cannot do with ES6 directly:\n\t```\n\ttaskq.load(\"./scriptDynamic1.js\")\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"setTimeout executed\");\n\t\t\t\tconsole.log(\"finally resolving\");\n\t\t\t\tres(true);\n\t\t\t},10000);\n\t\t\tconsole.log(\"dynamic script 1 'then' executed\");\n\t\t})\n\t\t/*Next then will not execute until the above is resolved*/\n\t\t.then(function(res){\n\t\t\tconsole.log(\"dynamic script 1 'then-2' executed\");\n\t\t});\n\t\t/*Meanwhile the entire downstream thread will wait for these tasks to finish*/\n\t```\n- Uses async script tags\n- Does not dictate anything about your app structure. Whether you want use separate async script tags, or bundle them.\n- No modifying required to your existing scripts other than wrapping them around iief (immediately invoked function expression) and *pushing* them to the taskq object.\n\n## API [⏎](#api)\n\nThere are some terms used throught out the documentation:\n\n### Terms\n\n- **iief**: immediately invoked function expression\n- **main thread** : this refers to the list of functions pushed to the taskq object before calling *taskq.perform* method. This is called automatically on 'onload' event. Dynamically loaded scripts have their separete queue (immediateTasks) that is handled implicitly.\n- **dynamic import/dynamic load** : this is to refer whenever you call *taskq.load* method to start loading scripts somehere within main thread (or outside later if you want). Everything you load is async but their execution can be controlled by you.\n- **taskq**: this is the main taskq global object. Although you can change its name using the script attribute, its default is assumed here.\n- **module pattern**: Although taskq only requires you to push the functions to be executed, to avoid leaking to global, a general module pattern is as follows:\n\n```\n/*outer iief*/\n!function(){\n\tfunction someFunctionYouWantToExecute (someArguments) {\n\t\t/*some stuff like taskq.export, taskq.load*/\n\t}\n\ttaskq.push(someFunctionYouWantToExecute);\n}()\n```\n\n### Methods\n\n\u003e taskq.version()\n\nReturns the version string.\n\n\u003e taskq.push(function)\n\nPushes the function to the main thread or the immediate thread (for dynamic imports) implicitly and return taskq it self, so you can do:\n\n```\n//Define functions\nfunction f1(){...};\nf1._taskqId = \"f1\";\nfunction f2(){...};\nf2._taskqId = \"f2\";\nf2._taskqWaitFor = [\"f1\"];\nfunction f3(){...};\nf3._taskqId = \"f3\";\nf3._taskqWaitFor = [\"f2\"];\n//Push to queue\ntaskq.push(f1).push(f2).push(f3);\n\n```\nPushed functions do not execute automatically, you will have to call *taskq.perform()* to start shifting and executing it. In your main HTML, perform is automatically called for you on 'onload' event.\n\nIf you push a variable that is not a function, it will be skipped and you will get a console message: \"not a function ref\".\n\n\u003e taskq.export(variable,aliasString)\n\nExports any type of variable with the given alias. These exported variables are available to the pushed functions. Suppose a *previouslyPushedFunction* in the main thread called *taskq.export({value:4},\"someObject\")*:\n\n```\n/*outer iief*/\n!function(){\n\tfunction someFunctionYouWantToExecute (someObject) {\n\t\t/*someObject is available here*/\n\t}\n\tsomeFunctionYouWantToExecute.taskqWaitFor = [\"previouslyPushedFunction\"];\n\ttaskq.push(someFunctionYouWantToExecute);\n}()\n```\n\nArguments order does not matter. \n\nExported variables live until *taskq.perform* finishes executing all the functions in the main thread. If there are no more pointers somewhere else in your code, they can be garbage collected. Later you can repopulate the exports by calling *taskq.export* again. Next time you call perform, it will again clear and so on.\n\n\u003e taskq.load(\"./someScript.js\")\n\nWill pause the main thread, and start loading the given script. Its iief will be immediately executed and pushed functions will be added to the immediate queue to be executed. Returns a *thennable* object which you can attach then or catch clauses. \n\nOther dynamic loads and the main thread will wait for this load to complete its iief, pushed functions and then/catch clauses.\n\n\u003e thennable.then(function(resolver){...})\n\nAttaches the thennable a function to be executed, and return the thennable itself. Attached thens are executed in order. Functions within thens are passed an optional resolver argument. If you do not call *resolver.init;* , the next then clause will execute as soon as this then clause is executed. If you call *resolver.init;* , somewhere else within the current then clause you should call *resolver(true)* or *resolver(false)* to proceed to the next then. \n\nWhen using resolver, the entire main thread and the rest of the then clauses will wait for it to resolve.\n\n\u003e thennable.catch(function(){...})\n\nAttaches a catch clause to the thennable shall any of the thens resolve with a *falsey* value. Attaching multiple catch clauses overrides the previous one.\n\n\u003e resolver.init\n\nTells the current then clause to block rest of the thens and the main thread and wait until it is resolved.\n\n\u003e resolver(variable)\n\nConverts the variable to \"boolean\" and resolves with that value. Returns always true unless you try to resolve more than once within the same then clause. You can only resolve once, resolving more than once does not have any effect -\u003e only the first resolve value is recorded.\n\n\u003e resolve.value\n\nGives the boolean value the resolver resolved with. Cannot be set.\n\n\u003e taskq.pause;\n\nPauses the entire taskq main thread, thens etc. If any functions were called at the time pause was called such as pushed functions or setTimeout, they are executed and the rest is halted. When paused, taskq is still running but does not proceed.\n\n\u003e taskq.paused;\n\nReturns true of false whether taskq is paused or not. Cannot be set manually.\n\n\u003e taskq.resume;\n\nResumes the taskq.\n\n\u003e taskq.running;\n\nReturns true or false based on taskq running state. It will return false once the *taskq.perform()* method finished the main thread. If you start another main thread, it return true until perform completes again.\n\n\u003e taskq.perform()\n\nStarts performing the pushed functions in the main thread. This is automatically called for you on the 'onload' event.\n\nLater if you start another main thread by pushing functions to taskq, you should manually call this method in the end. \n\nPerform will automatically clear all the exports once it is complete.\n\n\u003e taskq.flush(\"main\"|\"script\")\n\nThis is automatically called by the *taskq.perform* method in the end. You normally should not call this method manually. If you pass \"main\" as argument, then all the pushed functions to the main thread and the exported variables will be cleared. If you pass \"script\", only the immediate tasks (pushed functions within dynamic imports) are cleared.\n\n\u003e taskq.minPause = Number\n\nYou can use this *setter* to set the minimum time in milliseconds between the execution of pushed functions in the main thread. You can also configure this by adding an \"data-min-pause\" attribute to the script tag of taskq.\n\n\n## Reading [⏎](#reading)\n\nI advise you to take a look at below Medium posts:\n- [**Queued Async (pseudo-) modules with ES5**](https://medium.com/@ibowankenobi/queued-async-pseudo-modules-with-es5-812f99fed209)\n- [**Pausing/resuming browser \u0026 app logic using Taskq.js**](https://medium.com/@ibowankenobi/pausing-resuming-browser-app-logic-using-taskq-js-884ec5a8ce86)\n- [**Get that google PSI score higher**](https://medium.com/@ibowankenobi/get-that-google-psi-score-higher-28a7c992966e)\n\n## What does it do? [⏎](#what-does-it-do)\n\nThis project has evolved to the degree that is now a full blown module system that can be used instead of ES6 import/export or other module proposals. Perhaps it can be better illustrated in answer I have written in Hashnode:\n\n\u003e ### [Modules in JavaScript confusion](https://hashnode.com/post/modules-in-javascript-confusion-cjfc32m6f000a0as2os9nhf75)\n\n~~I was playing around with the idea of writing a module pattern for ES5, well not like a full-blown module definition but\na mini script to execute async scripts with clojures. So this will allow you to add async script tags and execute them with order \nwhile not leaking references to the global scope. This is by no means a replacement for es6 module pattern/AMD/CommonJS and is experimental.~~\n\n## Usage [⏎](#usage)\n\nTake a look at this minimal html, which also is included in the repository:\n\n```\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\t\u003chead\u003e\n\t\t\u003cmeta charset=\"utf-8\"\u003e\n\t\t\u003cstyle\u003e\n\t\t\u003c/style\u003e\n\t\u003c/head\u003e\n\t\u003cscript type=\"text/javascript\" src=\"../taskq.js\" charset=\"UTF-8\"\u003e\u003c/script\u003e\n\t\u003cscript type=\"text/javascript\" src=\"./test2.js\" charset=\"UTF-8\" async\u003e\u003c/script\u003e\n\t\u003cscript type=\"text/javascript\" src=\"./test0.js\" charset=\"UTF-8\" async\u003e\u003c/script\u003e\n\t\u003cscript type=\"text/javascript\" src=\"./test1.js\" charset=\"UTF-8\" async\u003e\u003c/script\u003e\n\t\u003c/head\u003e\n\t\u003cbody\u003e\n\t\t\u003cdiv class=\"row\"\u003e\u003c/div\u003e\n\t\u003c/body\u003e\n\u003c/html\u003e\n```\n\nOnly the taskq.js is synchronious, the others have their order shuffled with async attribute. The taskq.js script\nexposes the default taskq object, which has 2 main methods: *push* and *export*\nA \"global-name\" attribute can be added to the main script which will then change the exposed variable name from 'taskq' to 'hmm' for example:\n\n```\n\u003cscript type=\"text/javascript\" src=\"../taskq.js\" global-name=\"hmm\" charset=\"UTF-8\"\u003e\u003c/script\u003e\n/*'hmm' refers to the taskq object*/\n```\nIf you want to control the speed of which the function executions take place, then use the \"data-min-pause\" attribute:\n\n```\n\u003cscript type=\"text/javascript\" src=\"../taskq.js\" data-min-pause=\"2000\" charset=\"UTF-8\"\u003e\u003c/script\u003e\n/*'hmm' refers to the taskq object*/\n```\nAbove snippet will execute pushed functions to taskq with an interval of 2000ms. You can change the minimum pause value during runtime as well:\n\n```\ntaskq.minPause = 1000; //1000ms pause between executions\n```\n\nWithin each script you have the outermost clojure:\n\n```\n!function(){ //outermost clojure\n\t/*...some stuff...*/\n\tfunction toBeExported(){\n\t\t/*...some stuff...*/\n\t}\n\t/*...some stuff...*/\n}()\n```\n\nTo execute a function with some order, give it a _taskqId tag, a _taskqWaitFor array that lists the ids of other functions to be executed first, and \nlastly some variable name in DOMString that will be used as 'this' (so, \"refToThis\" below should be exported by another function beforehand like taskq.export(obj,\"refToThis\")).\nNone of these property names are mandatory:\n\n```\n!function(){\n\t/*...some stuff...*/\n\tfunction toBeExported(){\n\t\t/*...some stuff...*/\n\t}\n\ttoBeExported._taskqId = \"someId\";\n\ttoBeExported._taskqWaitFor = [\"someOtherId\",..];\n\ttoBeExported._taskqScope = \"refToThis\";\n\ttaskq.push(toBeExported);\n}()\n```\n\nYou can also export an object/primitive and make it available to another function:\n\n```\n!function(){\n\t/*...some stuff...*/\n\tvar someObject = {...};\n\tfunction toBeExported(){\n\t\t/*...some stuff...*/\n\t\ttaskq.export(someObject,\"refToSomeObject\");//export someObject as 'refToSomeObject'\n\t\ttaskq.export(5,\"a_primitive\");\n\t}\n\ttoBeExported._taskqId = \"someId\";\n\ttoBeExported._taskqWaitFor = [\"someOtherId\",..];\n\ttoBeExported._taskqScope = \"refToThis\";\n\ttaskq.push(toBeExported);\n}()\n```\n\nThen, in another function that executes after the above, the exported variable will be available as 'refToSomeObject':\n\n```\n!function(){\n\t/*...some stuff...*/\n\tfunction currentFunction (refToSomeObject,a_primitive){\n\t\t/*...some stuff with refToSomeObject...*/\n\t\t/*...some stuff with a_primitive...*/\n\t}\n\tcurrentFunction._taskqId = \"loadend\";\n\ttaskq.push(currentFunction);\n}()\n```\n\nAs shown above, there are special keywords for Id names which automatically is executed last or first:\n\n```\n[\"start\",\"init\",\"begin\",\"loadstart\",\"loadStart\"]// _taskqId that matches one of these will be executed first\n[\"end\",\"defer\",\"finish\",\"loadend\",\"loadEnd\"]// _taskqId that matches one of these will be executed last\n```\n\nIf more than one pushed function has the same \"loadstart\"/\"loadend\" etc keyword, then they are executed in the order they are pushed with respect to each other.\n\nEventually all pushed functions are executed at the 'load' event (by the internal *perform* method) and the internal references to the pushed and exported objects are flushed (by the internal *flush* method).\n\nIf you want me to extend the capability to dynamically important scripts after the 'load' event, let me know.\n\nCheck out the **[MINIMAL EXAMPLE](#example---2)** and also **[THIS](https://medium.com/@ibowankenobi/queued-async-pseudo-modules-with-es5-812f99fed209)** medium post. Also you can support me at my **[PATREON](https://www.patreon.com/ibrahimTanyalcin)** page.\n\n## Changelog [⏎](#changelog)\n\n#### v 2.2.0\n- Updated the sorting function to behave stable in Chrome. Now you also get the amount it has taken in milliseconds to sort the tasks.\n\n\n## Examples [⏎](#examples)\n\nIn each of the example, take a look at the html, and then open the inspector to look at the console messages to reveal execution pattern of functions. \n\nYou can open the html file of each example and inspect the console messages. All examples share a similar document head:\n\n```\n\u003cscript type=\"text/javascript\" src=\"../../taskq.js\" charset=\"UTF-8\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" src=\"./script2.js\" charset=\"UTF-8\" async\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" src=\"./script0.js\" charset=\"UTF-8\" async\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" src=\"./script1.js\" charset=\"UTF-8\" async\u003e\u003c/script\u003e\n```\nThe expected execution order of the scripts are:\n\n\u003e **script 0 --\u003e script 1 --\u003e script 2**\n\nThe execution order is controlled by attaching *_taskqId* (any javascript variable type) and *_taskqWaitFor* (array of '*taskqId*'s) properties to the *pushed* functions inside iiefs.\n\nNote that **the first 3 lines of console messages** in the below examples can vary as the iiefs can execute in any order due to the *async* attribute of the script tags.\n\nAlthough you should carefully examine all the scripts in each example, some important script for each example is highlighted, which is usually **'script1'**. \n\n### Example - 1\n\nThis example has been explained in detail [**HERE**](https://medium.com/@ibowankenobi/queued-async-pseudo-modules-with-es5-812f99fed209).\n\n### Example - 2\n\n\u003e Summary: The main thread will wait for completion of any dynamically imported (loaded) scripts and their then clauses, and will resume afterwards.\n\n\u003e script 1:\n\n```\n!function(){\n\tfunction script1(){\n\t\tconsole.log(\"script1 executed\");\n\t\ttaskq.load(\"./scriptDynamic.js\")\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 'then' executed\");\n\t\t})\n\t}\n\tscript1._taskqId = \"script1\";\n\tscript1._taskqWaitFor = [\"script0\"];\n\ttaskq.push(script1);\n\tconsole.log(\"scrip1 iief executed\");\n}()\n```\n\n\u003e console:\n\n```\nscrip0 iief executed\nscrip2 iief executed\nscrip1 iief executed\nscript0 executed\nscript1 executed\nDynamic Script loaded\ndynamic script 'then' executed\nscript2 executed\n```\n\u003e explanation:\n\nAs expected iiefs execute first. And then based on the *_taskqWaitFor* properties, script 0 --\u003e script 1 --\u003e script 2 is executed. But since script 1 dynamically imports another script, the main thread will wait for the dynamic import (and then handlers) and then resume for script 2.\n\n### Example - 3\n\n\u003e Summary: Everytime a function is pushed to the main thread, the main thread will wait for all dynamic loads within this function.\n\n\u003e script 0 (similarly scripts 1 and 2):\n\n```\n!function(){\n\tfunction script0(){\n\t\tconsole.log(\"script0 executed\");\n\t\ttaskq.load(\"./scriptDynamic0.js\")\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 0 'then' executed\");\n\t\t});\n\t}\n\tscript0._taskqId = \"script0\";\n\ttaskq.push(script0);\n\tconsole.log(\"scrip0 iief executed\");\n}()\n```\n\n\u003e console:\n\n```\nscrip2 iief executed\nscrip0 iief executed\nscrip1 iief executed\nscript0 executed\nDynamic-0 Script loaded\ndynamic script 0 'then' executed\nscript1 executed\nDynamic-1 Script loaded\ndynamic script 1 'then' executed\nscript2 executed\nDynamic-2 Script loaded\ndynamic script 2 'then' executed\n```\n\n\u003e explanation\n\nHere all the main scripts import a single dynamic module. And each time, the main thread will pause/resume once the dynamic import and its then handlers are executed. \n\n### Example - 4\n\n\u003e Summary: The main thread will also wait for nested dynamic loads within a pushed function.\n\n\u003e script 1:\n\n```\n!function(){\n\tfunction script1(){\n\t\tconsole.log(\"script1 executed\");\n\t\ttaskq.load(\"./scriptDynamic1.js\")\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 1 'then' executed\");\n\t\t})\n\t\t.then(function(){\n\t\t\ttaskq.load(\"./scriptDynamic1_2.js\")\n\t\t\t.then(function(){\n\t\t\t\tconsole.log(\"dynamic script 1_2 'then' executed\");\n\t\t\t});\n\t\t})\n\t\t.then(function(){\n\t\t\tconsole.log(\"script 1 final then clause\");\n\t\t});\n\t}\n\tscript1._taskqId = \"script1\";\n\tscript1._taskqWaitFor = [\"script0\"];\n\ttaskq.push(script1);\n\tconsole.log(\"scrip1 iief executed\");\n}()\n```\n\n\u003e console:\n\n```\nscrip2 iief executed\nscrip0 iief executed\nscrip1 iief executed\nscript0 executed\nDynamic-0 Script loaded\ndynamic script 0 'then' executed\nscript1 executed\nDynamic-1 Script loaded\ndynamic script 1 'then' executed\nscript 1 final then clause\nDynamic-1_2 Script loaded\ndynamic script 1_2 'then' executed\nscript2 executed\nDynamic-2 Script loaded\ndynamic script 2 'then' executed\n```\n\n\u003e explanation:\n\nIn this example, all scripts (0,1 and 2) dynamically import their own scripts. The main thread (script 0 --\u003e script 1 --\u003e script2) will wait for each script's dynamic imports to finish.\n\nWhen you are dynamically importing a script:\n\n- that script's iief is first executed\n- then any functions it pushed to taskq is executed (these are pushed to a different 'immediate' queue rather than the main threads queue)\n- then all the 'then' handlers are executed in order\n- If during execution any other dynamic import is detected, it is added to the script queue to be executed AFTER all the thens (or the catch if any) for this dynamic import is executed.\n\nSo in case of the script 1, the 'scriptDynamic1' is loaded, then all the thens are executed. The second then dynamically imports another script 1_2, so this is added to the queue. That is why you see \"script 1 final then clause\" first. This might give you the impression that the second then did not execute, but actually it does and adds the scriptDynamic1_2 to the queue.\n\nAfter all the thens are executed, \"scriptDynamic1_2.js\" gets loaded and its then handlers execute. After all these layers are done within script1, main thread continues with script 2.\n\n### Example - 5\n\n\u003e Summary: Within a dynamically loaded module/script, first the iief is executed, then its pushed function is executed, then all the then clauses are executed in order.\n\n\u003e script 1:\n\n```\n!function(){\n\tfunction script1(){\n\t\tconsole.log(\"script1 executed\");\n\t\ttaskq.load(\"./scriptDynamic1.js\")\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 1 'then' executed\");\n\t\t})\n\t\t.then(function(){\n\t\t\ttaskq.load(\"./scriptDynamic1_2.js\")\n\t\t\t.then(function(){\n\t\t\t\tconsole.log(\"dynamic script 1_2 'then' executed\");\n\t\t\t});\n\t\t})\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 1_2 final 'then' executed\");\n\t\t});\n\t\t\n\t\ttaskq.load(\"./scriptDynamic1_3.js\")\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 1_3 'then' executed\");\n\t\t})\n\t\t.then(function(){\n\t\t\ttaskq.load(\"./scriptDynamic1_4.js\")\n\t\t\t.then(function(){\n\t\t\t\tconsole.log(\"dynamic script 1_4 'then' executed\");\n\t\t\t});\n\t\t})\n\t\t.then(function(){\n\t\t\tconsole.log(\"script 1 final then clause\");\n\t\t});\n\t}\n\tscript1._taskqId = \"script1\";\n\tscript1._taskqWaitFor = [\"script0\"];\n\ttaskq.push(script1);\n\tconsole.log(\"scrip1 iief executed\");\n}()\n```\n\n\u003e console:\n\n```\nscrip0 iief executed\nscrip1 iief executed\nscrip2 iief executed\nscript0 executed\nDynamic-0 Script loaded\ndynamic script 0 'then' executed\nscript1 executed\nDynamic-1 Script loaded\ndynamic script 1 'then' executed\ndynamic script 1_2 final 'then' executed\nDynamic-1_3 Script loaded\nDynamic script 1_3 pushed me!\ndynamic script 1_3 'then' executed\nscript 1 final then clause\nDynamic-1_2 Script loaded\ndynamic script 1_2 'then' executed\nDynamic-1_3_2 Script loaded\ndynamic script 1_3_2 'then' executed\nDynamic-1_4 Script loaded\ndynamic script 1_4 'then' executed\nscript2 executed\nDynamic-2 Script loaded\ndynamic script 2 'then' executed\n```\n\n\u003e explanation:\n\nWithin script 1, there are 2 layers. An outer layer that loads 'scriptDynamic1.js' and 'scriptDynamic1_3.js', and an inner layer that loads other scripts.\n\nSo within the flow of script 1:\n\n- First 'scriptDynamic1.js' is seen. The thens are recorded. \n- Next 'scriptDynamic1_3.js' is seen and added to the queue to be executed later.\n- The thens of 'scriptDynamic1.js' is executed, amongst these, the second then clause loads 'scriptDynamic1_2.js'. This is added to the queue.\n- Once the thens of 'scriptDynamic1.js' are all executed. The script queue is shifted and 'scriptDynamic1_3.js' is loaded. \n- First the pushed functions within 'scriptDynamic1_3.js' are all executed. After that, then thens are executed in order. Within these thens, the second then loads another 'scriptDynamic1_4.js'. This is added to the script queue to be loaded after 'scriptDynamic1_2.js.\n- After all the thens of 'scriptDynamic1_3.js' are executed, 'scriptDynamic1_2.js' starts loading and its then clauses are executed.\n- Last, 'scriptDynamic1_4.js' gets loaded and its then clauses are executed.\n- The main thread resumes from script 2.\n\n### Example - 6\n\n\u003e Summary: Dynamicall loaded scripts/modules and main initial script tags share the same pattern: a function wrapped inside iief where it is ultimately pushed to the taskq by the iief. However, dynamically loaded modules do not push the functions to the main thread, but to a separate 'immediate' thread. This is done implicitly.\n\n\u003e scriptDynamic1.js:\n\n```\n!function(){\n\tfunction someFunction(){\n\t\tconsole.log(\"Dynamic-1 pushed me!\");\n\t}\n\ttaskq.push(someFunction);\n\tconsole.log(\"Dynamic-1 Script loaded\");\n}()\n```\n\n\u003e console:\n\n```\nscrip2 iief executed\nscrip0 iief executed\nscrip1 iief executed\nscript0 executed\nDynamic-0 Script loaded\nDynamic-0 pushed me!\ndynamic script 0 'then' executed\nscript1 executed\nDynamic-1 Script loaded\nDynamic-1 pushed me!\ndynamic script 1 'then' executed\ndynamic script 1_2 final 'then' executed\nDynamic-1_3 Script loaded\nDynamic script 1_3 pushed me!\ndynamic script 1_3 'then' executed\nscript 1 final then clause\nDynamic-1_2 Script loaded\ndynamic script 1_2 'then' executed\nDynamic-1_3_2 Script loaded\nDynamic-1_3_2 pushed me!\ndynamic script 1_3_2 'then' executed\nDynamic-1_4 Script loaded\ndynamic script 1_4 'then' executed\nscript2 executed\nDynamic-2 Script loaded\nDynamic-2 pushed me!\ndynamic script 2 'then' executed\n```\n\n\u003e explanation:\n\nThe difference between this example and [example 5](#example---5) is dynamically imported functions also push another function to the queue. \n\nWhen dynamically loading scripts, note that the pushed functions execute before the then clauses as shown in the console messages.\n\nDynamically loaded scripts do not push functions into the queue of the main thread but instead have a private 'immediate queue'. You might as well then ask why pushing is enabled inside dynamically loaded function wheras everthing could have been kept inside the iief. There are 2 reasons:\n\n- You can interchange scripts in the main thread with dynamic modules and vice versa without modifying your scripts.\n\n- While you are loading, you cannot control the iief, but since the pushed function has access to the exported variables, you can decide to execute or not execute this function based on some exported variables.\n\n### Example - 7\n\n\u003e Summary: Any pushed function in the main thread or dynamically loaded script can export a variable. These variables are accessible to all the functions. The life cycle of these exported variables are till the end of the main thread, where they are ultimately flushed automatically.\n\n\u003e scriptDynamic2.js: \n\n```\n!function(){\n\tfunction someFunction(Dynamic0,Dynamic1_3_2){\n\t\tconsole.log(\"Dynamic-2 pushed me!\");\n\t\tconsole.log(\"reading exported objects:\");\n\t\tconsole.log(Dynamic0);\n\t\tconsole.log(Dynamic1_3_2);\n\t}\n\ttaskq.push(someFunction);\n\tconsole.log(\"Dynamic-2 Script loaded\");\n}()\n```\n\n\u003e console:\n\n```\nscrip0 iief executed\nscrip1 iief executed\nscrip2 iief executed\nscript0 executed\nDynamic-0 Script loaded\nDynamic-0 pushed me!\nexporting 'Dynamic0'\ndynamic script 0 'then' executed\nscript1 executed\nDynamic-1 Script loaded\nDynamic-1 pushed me!\ndynamic script 1 'then' executed\ndynamic script 1_2 final 'then' executed\nDynamic-1_3 Script loaded\nDynamic script 1_3 pushed me!\ndynamic script 1_3 'then' executed\nscript 1 final then clause\nDynamic-1_2 Script loaded\ndynamic script 1_2 'then' executed\nDynamic-1_3_2 Script loaded\nDynamic-1_3_2 pushed me!\nexporting 'Dynamic1_3_2'\ndynamic script 1_3_2 'then' executed\nDynamic-1_4 Script loaded\ndynamic script 1_4 'then' executed\nscript2 executed\nDynamic-2 Script loaded\nDynamic-2 pushed me!\nreading exported objects:\nObject\nObject\ndynamic script 2 'then' executed\n```\n\n\u003e explanation:\n\nIdentical to example 6, with the addition of 'scriptDynamic0.js' and 'scriptDynamic1_3_2.js' exporting 2 objects. These objects are later available to other scripts in the main thread or dynamically loaded scripts. \n\nIn this case, script 2 dynamically loads another script that reads these variables from the exported objects and logs them.\n\n### Example - 8\n\nThis is identical to [example 1](#example---1) with the addition of dynamically loaded scripts. It demonstrates how nested loads (dynamically loaded script loading another one) are handled.\n\n### Example - 9\n\n\u003e Summary: The then clauses gets passed a resolver argument. Thens are executed immediately unless you call *res.init*. You can later resolve it within the then clause by *res(true|false)*. You cannot resolve it twice, to check the value, use *res.value*. Resolving with falsey value will result in the next then clauses to be skipped and execution of a catch clause, if any. \n\n\u003e script1.js:\n\n```\n!function(){\n\tfunction script1(){\n\t\tconsole.log(\"script1 executed\");\n\t\ttaskq.load(\"./scriptDynamic1.js\")\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"setTimeout executed\");\n\t\t\t\tconsole.log(\"finally resolving\");\n\t\t\t\tres(true);\n\t\t\t},10000);\n\t\t\tconsole.log(\"dynamic script 1 'then' executed\");\n\t\t})\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"'then-2' finally resolving\");\n\t\t\t\tres(true);\n\t\t\t},5000);\n\t\t\tconsole.log(\"dynamic script 1 'then-2' executed\");\n\t\t})\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 1 'then-3' executed\");\n\t\t});\n\t}\n\tscript1._taskqId = \"script1\";\n\tscript1._taskqWaitFor = [\"script0\"];\n\ttaskq.push(script1);\n\tconsole.log(\"scrip1 iief executed\");\n}()\n```\n\n\u003e console:\n\n```\nscrip2 iief executed\nscrip1 iief executed\nscrip0 iief executed\nscript0 executed\nDynamic-0 Script loaded\ndynamic script 0 'then' executed\nscript1 executed\nDynamic-1 Script loaded\ndynamic script 1 'then' executed\nsetTimeout executed\nfinally resolving\ndynamic script 1 'then-2' executed\n'then-2' finally resolving\ndynamic script 1 'then-3' executed\nscript2 executed\nDynamic-2 Script loaded\ndynamic script 2 'then' executed\n```\n\n\u003e explanation:\n\nYou might not have realized but every function passed to a *then* caluse gets passed with a *resolver* argument. This argument is essentially a function that will convert any value passed to it to \"boolean\" and resolve with that boolean value.\n\nTo enable resolver within a then clause you first have to:\n```\nres.init\n```\nNow everthing inside that then clause will execute but the next then clause will not start until somehere within the the current then clause you do this:\n```\nres(true)\n```\nYou could have also resolved with a *falsey* value. In that case, the rest of the thens for this dynamic load will be skipped and if any *catch* clauses have been previously attached, the latest attached *catch* clause will be executed before the next dynamic import is popped from the script queue or the main thread continues.\n\nIn this particular case first then clause within 'script1.js' is executed. The next then will wait until this is resolved within the setTimeout in about 10 seconds. Then next then clause will also resolve in another 5 seconds. After that, the third then clause executes and the main thread continues to script2.\n\n### Example - 10\n\n\u003e Summary: Then clauses will wait for each others *res* to resolve before they execute. This is also true for dynamically loaded scripts and their then clauses. The main thread will wait for all of these nested clauses to complete and resolve before continuing.\n\n\u003e script1.js:\n\n```\n!function(){\n\tfunction script1(){\n\t\tconsole.log(\"script1 executed\");\n\t\ttaskq.load(\"./scriptDynamic1.js\")\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"setTimeout executed\");\n\t\t\t\ttaskq.load(\"./scriptDynamic1_1.js\")\n\t\t\t\t.then(function(res){\n\t\t\t\t\tres.init;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tconsole.log(\"dynamic script 1_1 'then' executed\");\n\t\t\t\t\t\tres(true);\n\t\t\t\t\t},5000)\n\t\t\t\t});\n\t\t\t\tconsole.log(\"finally resolving\");\n\t\t\t\tres(true);\n\t\t\t},10000);\n\t\t\tconsole.log(\"dynamic script 1 'then' executed\");\n\t\t})\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"dynamic script 1 'then-2' executed\");\n\t\t\t\tres(true);\n\t\t\t},5000)\n\t\t})\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 1 'then-3' executed\");\n\t\t});\n\t}\n\tscript1._taskqId = \"script1\";\n\tscript1._taskqWaitFor = [\"script0\"];\n\ttaskq.push(script1);\n\tconsole.log(\"scrip1 iief executed\");\n}()\n```\n\n\u003e console:\n\n```\nscrip2 iief executed\nscrip0 iief executed\nscrip1 iief executed\nscript0 executed\nDynamic-0 Script loaded\ndynamic script 0 'then' executed\nscript1 executed\nDynamic-1 Script loaded\ndynamic script 1 'then' executed\nsetTimeout executed\nfinally resolving\ndynamic script 1 'then-2' executed\ndynamic script 1 'then-3' executed\nDynamic-1_1 Script loaded\ndynamic script 1_1 'then' executed\nscript2 executed\nDynamic-2 Script loaded\ndynamic script 2 'then' executed\n```\n\n\u003e explanation:\n\nThis is similar to [example 9](#example---9). The difference is that the first then clause dynamically imports another script 'scriptDynamic1_1.js' within the setTimeout before it resolves.\n\nThe 3 first layer then clauses are executed in order, within the first then clause the loading of 'scriptDynamic1_1.js' is added to the script queue. Once the first layer 3 then clauses are executed, 'scriptDynamic1_1.js' executes. The (second layer) then clause of 'scriptDynamic1_1.js' resolves in about 5 seconds. After that, the main thread continues with script2.\n\n### Example - 11\n\n\u003e Summary: When a then clause resolves with a *falsey* value, its remaining then clauses are skipped and the **latest attached** catch clause is executed. \n\n\u003e script1.js:\n\n```\n!function(){\n\tfunction script1(){\n\t\tconsole.log(\"script1 executed\");\n\t\ttaskq.load(\"./scriptDynamic1.js\")\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"setTimeout executed\");\n\t\t\t\ttaskq.load(\"./scriptDynamic1_1.js\")\n\t\t\t\t.then(function(res){\n\t\t\t\t\tres.init;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tconsole.log(\"dynamic script 1_1 'then' executed\");\n\t\t\t\t\t\tres(true);\n\t\t\t\t\t},5000)\n\t\t\t\t});\n\t\t\t\tconsole.log(\"finally resolving\");\n\t\t\t\tres(true);\n\t\t\t},10000);\n\t\t\tconsole.log(\"dynamic script 1 'then' executed\");\n\t\t})\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tres(false);\n\t\t\t\ttaskq.export(false,\"status\");\n\t\t\t\tconsole.log(\"catch will be executed, rest of the thens will be skipped.\");\n\t\t\t},5000);\n\t\t})\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"dynamic script 1 'then-2' executed\");\n\t\t\t\tres(true);\n\t\t\t},5000)\n\t\t})\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 1 'then-3' executed\");\n\t\t})\n\t\t.catch(function(){\n\t\t\tconsole.log(\"This is the catch function attached!\");\n\t\t});\n\t}\n\tscript1._taskqId = \"script1\";\n\tscript1._taskqWaitFor = [\"script0\"];\n\ttaskq.push(script1);\n\tconsole.log(\"scrip1 iief executed\");\n}()\n```\n\n\u003e console:\n\n```\nscrip0 iief executed\nscrip1 iief executed\nscrip2 iief executed\nscript0 executed\nDynamic-0 Script loaded\ndynamic script 0 'then' executed\nscript1 executed\nDynamic-1 Script loaded\ndynamic script 1 'then' executed\nsetTimeout executed\nfinally resolving\ncatch will be executed, rest of the thens will be skipped.\nThis is the catch function attached!\nDynamic-1_1 Script loaded\nI will NOT execute!\ndynamic script 1_1 'then' executed\nscript2 executed\nDynamic-2 Script loaded\ndynamic script 2 'then' executed\n```\n\n\u003e explanation:\n\nThis is almost identical to [example 10](#example---10) with the addition of second then clause resolving with a *falsey* value. The same then clause also exports a boolean variable called 'status'.\n\n Due resolving with false at second then clause, the rest of the then clauses do not execute. If any catch handler attached, it executes which in this case logged: \"This is the catch function attached!\".\n\n After thens are all executes, the script queue is shifted and \"./scriptDynamic1_1.js\" is loaded. Due to the exported boolean variable, the execution of the pushed function can react: in this case it logged: \"I will NOT execute!\".\n\n After the then clause of \"./scriptDynamic1_1.js\" is executed, the main thread continues from script2.\n\n ### Example - 12\n\n\u003e Summary: Then clauses can only be resolved with a boolean value. To share return values or other variables between then clauses or other functions, use the *taskq.export* method. Exporting a variable with the same alias overwrites it.\n\n \u003e scriptDynamic0.js:\n\n```\n!function(){\n\tconsole.log(\"Dynamic-0 Script loaded\");\n\tconsole.log(\"Exporting retValue\");\n\ttaskq.export({value:undefined},\"retValue\");\n}()\n```\n\n\u003e script1.js\n\n```\n!function(){\n\tfunction script1(retValue){\n\t\tconsole.log(\"script1 executed\");\n\t\ttaskq.load(\"./scriptDynamic1.js\")\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"setTimeout executed\");\n\t\t\t\ttaskq.load(\"./scriptDynamic1_1.js\")\n\t\t\t\t.then(function(res){\n\t\t\t\t\tres.init;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tconsole.log(\"dynamic script 1_1 said: \" + retValue.value);\n\t\t\t\t\t\tconsole.log(\"dynamic script 1_1 'then' executed\");\n\t\t\t\t\t\tres(true);\n\t\t\t\t\t},5000)\n\t\t\t\t});\n\t\t\t\tconsole.log(\"finally resolving\");\n\t\t\t\tres(true);\n\t\t\t},10000);\n\t\t\tconsole.log(\"dynamic script 1 'then' executed\");\n\t\t})\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tres(false);\n\t\t\t\ttaskq.export(false,\"status\");\n\t\t\t\tconsole.log(\"catch will be executed, rest of the thens will be skipped.\");\n\t\t\t},5000);\n\t\t})\n\t\t.then(function(res){\n\t\t\tres.init;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"dynamic script 1 'then-2' executed\");\n\t\t\t\tres(true);\n\t\t\t},5000)\n\t\t})\n\t\t.then(function(){\n\t\t\tconsole.log(\"dynamic script 1 'then-3' executed\");\n\t\t})\n\t\t.catch(function(){\n\t\t\tconsole.log(\"This is the catch function attached!\");\n\t\t});\n\t}\n\tscript1._taskqId = \"script1\";\n\tscript1._taskqWaitFor = [\"script0\"];\n\ttaskq.push(script1);\n\tconsole.log(\"scrip1 iief executed\");\n}()\n```\n\n\u003e scriptDynamic1_1.js:\n\n```\n!function(){\n\tfunction conditional(status,retValue){\n\t\tif (status) {\n\t\t\tconsole.log(\"I will execute!\");\n\t\t} else {\n\t\t\tconsole.log(\"I will NOT execute!\");\n\t\t\ttaskq.pause;\n\t\t\tsetTimeout(function(){\n\t\t\t\tretValue.value = \"I will NOT execute!\";\n\t\t\t\ttaskq.resume;\n\t\t\t},10000);\n\t\t}\n\t}\n\ttaskq.push(conditional);\n\tconsole.log(\"Dynamic-1_1 Script loaded\");\n}()\n```\n\n\u003e console:\n\n```\nscrip2 iief executed\nscrip0 iief executed\nscrip1 iief executed\nscript0 executed\nDynamic-0 Script loaded\nExporting retValue\ndynamic script 0 'then' executed\nscript1 executed\nDynamic-1 Script loaded\ndynamic script 1 'then' executed\nsetTimeout executed\nfinally resolving\ncatch will be executed, rest of the thens will be skipped.\nThis is the catch function attached!\nDynamic-1_1 Script loaded\nI will NOT execute!\ndynamic script 1_1 said: I will NOT execute!\ndynamic script 1_1 'then' executed\nscript2 executed\nDynamic-2 Script loaded\ndynamic script 2 'then' executed\n```\n\n\u003e explanation:\n\nThis is very similar to [example 11](#example---11) with an addition of passing then clause parameters about the previous pushed function.\n\nIn example 11, you might wonder is there any way for the then clause of \"./scriptDynamic1_1.js\" to react to what has been returned or done within the pushed function (open \"./scriptDynamic1_1.js\" and look for the function named \"conditional\", this was the pushed function).\n\nThis is possible using the *exports* and exporting a variable that is passed by reference (which is a javascript object).\n\nIn this particular case, \"scriptDynamic0.js\" exports a retValue variable which is:\n\n```\n{value:undefined}\n```\n\nNow other function within the main thread or dynamically loaded modules can access this object on demand and make changes to it.\n\nOnce \"./scriptDynamic1_1.js\" loads, it executes its pushed function (*conditional*), this function first pauses the entire main thread + execution of other thens/loads:\n\n```\ntaskq.pause\n```\n\n And within a setTimeout, it changes the value of \"retValue\" and finally resumes:\n\n ```\n retValue.value = \"I will NOT execute!\";\ntaskq.resume;\n ```\n\nAfter resuming, the then clause start executing. Since retValue is changed, now we can react to what has been executed previously, the then clause logs:\n\n```\ndynamic script 1_1 said: I will NOT execute!\n```\n\nYou can devise many other patterns using various combinations of *res* , *task.pause* and *taskq.resume*. \n\nAt any time during execution, whether at onload event or manual pushing functions after the load event of the browser, you can always query whether taskq is active by:\n\n```\ntaskq.running\n```\n\nIf you have any questions contact me at:\n\nibowankenobi@ibrahimtanyalcin.com","funding_links":["https://www.patreon.com/ibrahimTanyalcin"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibrahimtanyalcin%2Ftaskq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fibrahimtanyalcin%2Ftaskq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibrahimtanyalcin%2Ftaskq/lists"}