依傍RequireJs的用法写三个精英型的模块加载器

效仿RequireJs的用法写2个尊品型的模块加载器


在3.0 以往引入了新的措施。能够不在三个线程池里运行。

总结


  1. 下载js代码时自我用了ajax来兑现,所以对于跨域文件和CDN会有点难点,那一个可以改成创制script标签,钦定标签src,最终将document.head.appendChild(script),那样来消除,其余的例如使用XMLHttpRequest
    2.0,iframe等也足以的,能够试行一下。
  2. 分析代码时本人用了eval的情势,这一个eval在JavaScript里面是个抒几见,可以看看这个,假诺是用了地点创制script标签的点子的话,就不用本人eval了。
  3. 发现四个bug,存在循环重视时,代码会报错,还没去解决。RequireJs是这般处理的:模块a正视b,同时b依赖a,那种情景下b的模块函数被调用时,被传出的a是undefined,所以要求自身在b里面手动require一下a。

假设选择的具备网络得到都依靠这些来做,当有一个网络请求柱塞,就招致别的请求也柱塞了。

行使方法


详见表明: github
README.md

asyncTask.execute

Note: this function schedules the task on a queue for a single
background thread or pool of threads depending on the platform
version. When first introduced, AsyncTasks were executed serially on a
single background thread. Starting with
android.os.Build.VERSION_CODES.DONUT, this was changed to a pool of
threads allowing multiple tasks to operate in parallel. After
android.os.Build.VERSION_CODES.HONEYCOMB, it is planned to change
this back to a single thread to avoid common application errors caused
by parallel execution. If you truly want parallel execution, you can
use the executeOnExecutor version of this method with
THREAD_POOL_EXECUTOR; however, see commentary there for warnings on
its use. 

This method must be invoked on the UI thread.必须UI线程中调用

留神:那个函数让任务是以单线程队列格局或线程池队列方式运行,信赖于阳台版本而有所不一致。asyncTask第3次引入时,那个函数会让职责之后台单线程串行格局举办。从android.os.Build.VECR-VSION_CODES.DONUT(android
一.6)初始,它让允许职务在线程池中多使命并行执行。但在 android.os.Build.VE宝马X5SION_CODES.HONEYCOMB(android
3.0)之后,它又该回去了,变成了单线程执行的情势,原因是八线程并行执行简单吸引难点。假诺你真想并行执行职责,你能够采取别的三个本子:使用THREAD_POOL_EXECUTOTiggo参数的executeOnExecutor方法,但要注意接纳警告提醒

anyncTask.executeOnExecutor

This method is typically used with THREAD_POOL_EXECUTOR to allow
multiple tasks to run in parallel on a pool of threads managed by
AsyncTask, however you can also use your own Executor for custom
behavior. 

Warning: Allowing multiple tasks to run in parallel from a thread pool
is generally not what one wants, because the order of their operation
is not defined. For example, if these tasks are used to modify any
state in common (such as writing a file due to a button click), there
are no guarantees on the order of the modifications. Without careful
work it is possible in rare cases for the newer version of the data to
be over-written by an older one, leading to obscure data loss and
stability issues. Such changes are best executed in serial; to
guarantee such work is serialized regardless of platform version you
can use this function with SERIAL_EXECUTOR. 
This method must be invoked on the UI thread.
Parameters:
exec The executor to use. THREAD_POOL_EXECUTOR is available as a
convenient process-wide thread pool for tasks that are loosely
coupled.

其一法子一般和THREAD_POOL_EXECUTOOdyssey1起利用,允许多个职务在由AsyncTask管理的线程池中并行执行,可是你你也足以动用自定义行为的Executor。

 

警示:因为实施操作顺序并未有定义,平日状态下,允许两个职责在线程池中并行执行,其结果毫无是您想要的。例如:这一个职分都要去修改有个别状态值(诸如点击按钮写文件),因为从没鲜明的改动顺序,旧的修改恐怕会覆盖新修改的版本内容,导致不稳定数据丢失而变成叁个平安的难点。由此那种职分最为是串行执行;确定保证这个职分串行执行而不借助于阳台版本的办法是,使用SELANDIAL_EXECUTOR

落实原理


  1. config方法显明各类模块的依靠关系

  /* 记录模块访问地址和模块的依赖等信息 */
  Require.config({
    baseUrl: '/javascripts/',
    paths: {
      'moduleA': './moduleA.js',  // 相对于当前目录
      'moduleB': '/javascripts/moduleB.js',  // 不使用baseUrl
      'moduleC': 'moduleC.js',

      'moduleD': {
        url: 'moduleD.js',
        deps: ['moduleE', 'moduleF'],
      },
      ...
    },
    shim: {
      'moduleH': {
        url: 'moduleH.js',
        exports: 'log',
      },
    }
  });
  1. 多少请求进度分析

(1) config配置模块新闻时并不会触发互连网请求
(二)
在index.js主入口文件里选取require方法引用几个模块时,依据config配置文件构造一下独具模块的信赖分析树。按深度优先或是广度优先来遍历那几个依靠树,将兼具依赖依据正视顺序放进3个数组,最终实行数组去重处理,因为会出现注重重复的情景

  var dependsTree = new Tree('dependsTree');
  var dependsArray = [];
  var dependsFlag = {};  // 解决循环依赖

  // 创建树
  setDepends(depends, dependsTree);
  // 得到依赖数组
  sortDepends(dependsArray, dependsTree);
  // 数据去重
  arrayFilter(dependsArray);

  return dependsArray;

(3)
成立XH宝马X5对象异步下载数组里面包车型客车拥有js文件,遵照信赖顺序依次解析js代码,解析完成后触发回调函数,回调函数里传播各样模块的引用

  // ajax下载代码文件
  Utils.request(url, 'get', null, function(responseText){
    // 暂时保存
    _temp[module_name] = responseText;
  });

  // 文件下载完成后eval解析代码
  array.map(function(jsText){
    ...
    eval(jsText);
    ...
  });

  // 调用回调函数
  callback.apply(null, [dep1, dep2, dep3]);

 

前言


前段时间一贯想用单页开发技术写三个温馨的私人住房网址(使用es二〇一五),写了1部分之后,发现单页应用因为唯有贰个页面,所以率先次加载index.html时就要下载全部js文件,并且为了好管理各样部分的气象,须要划分页面包车型大巴1一效率区为顺序模块,es201五本身是不协理部分模块规范的(比如英特尔、CMD、CommonJs等),所以只能这么效仿达成:

  // global
  var spa = (function(){...})();

  // module blog
  spa.blog = (function(){
    ...
    return {
      do1: do1,
      do2: do2,
    };
  })();

  // module model
  spa.model = (function(){...})();

  // module shell
  spa.model = (function(){...})();

再正是逐1模块之间又存在有的借助关系,在index.html里面写script标签来载入模块时索要写很八个,同时也要依据信赖关系来规定书写顺序,页面逻辑混乱,如下:

  <script type="text/javascript" src="/javascripts/spa.utils.js"></script>
  <script type="text/javascript" src="/javascripts/spa.model.js"></script>
  <script type="text/javascript" src="/javascripts/spa.mock.js"></script>
  <script type="text/javascript" src="/javascripts/spa.chat.js"></script>
  <script type="text/javascript" src="/javascripts/spa.blog.js"></script>
  <script type="text/javascript" src="/javascripts/spa.action.js"></script>
  <script type="text/javascript" src="/javascripts/spa.shell.js"></script>

在此之前用过RequireJs(1个风行的JavaScript模块加载器),它是用同构js的架构来写的,所以node.js环境下也能应用。笔者想本人能够品尝一下写1个中配版的js模块加载器
requireJs-nojsja
来应付一下自己这几个单页网址,当然只是大略模仿了重点意义。

 

Contents

  1. 前言
  2. 回看RequireJs的骨干用法
  3. 实现原理
  4. 应用格局
  5. 总结
class TaskHelper {

    public static <P, T extends AsyncTask<P, ?, ?>> void execute(T task) {
        execute(task, (P[]) null);
    }

    @SuppressLint("NewApi")
    public static <P, T extends AsyncTask<P, ?, ?>> void execute(T task, P... params) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
        } else {
            task.execute(params);
        }
    }
}

回想RequireJs的主导用法


  1. 安顿模块新闻

  requirejs.config({
      baseUrl: '/javascripts',  // 配置根目录
      paths: {
        moduleA: 'a.js',
        moduleB: 'b.js',
        moduleC: 'c.js',
      },
      shim: {  // 配置不遵循amd规范的模块
        moduleC: {
          exports: 'log',
          deps: ['moduleA']
        }
      },
  });
  1. 概念1个模块

  define(name, ['moduleA', 'moduleB'], function(a, b){
    ...
    return {
      do: function() {
        a.doSomething();
        b.doAnother();
      }
    };
  });
  1. 引用三个模块

  // 引用模块
  require(['moduleA', 'moduleB'], function(a, b) {
    a.doSomething();
    b.doAnother();
  });

android
的AysncTask直接调用Execute会在在2个线程池里按调用的先后顺序依次执行。

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注