比如我要做一个H5页面,有一些动画效果,同时带音频播放
目前我有一个app模块为主要逻辑。有一个sound模块用来初始化音频。
我是使用SoundManager 2这个音频库来初始我的音频,需要的使用方法如下。
//sound.js define(["SoundManager"],function(sm2){ var mySound; sm2.soundManager.setup({ url:'js/sm2/swf/', onready: function() { mySound = sm2.soundManager.createSound({ url: 'sound/sound1.mp3', autoLoad: true }); } }); return { mySound:mySound }; });
但是实际上 onready方法是在音频开始加载后才异步执行的。这使得我在app中获取到的mySound是undefined。
//app.js define(["sound"], function(sound) { var mySound = sound.mySound;// undefined });
于是我改成在return的时候这样写
//sound.js修改后的return return{ getMySound:function(){ return mySound; } };
然后在app中使用的时候每次都是如下:
//app.js define(["sound"], function(sound) { var mySound = sound.getMySound(); if(typeof mySound !== 'undefined'){ //doSometing()... } });
我的模块化设计思路是不是有问题?在这种回调下怎么设计要好一些?
而且如果我要在mySound加载成功后再执行一些任务,就只能到sound.js中去做了。但是我又想把类似的任务放到app.js里。
如果在普通模式下。可能我是习惯了不断的回调深渊了,现在接触模块化设计有点不够灵光。
题主所遇到的问题,可以进行拆分。
requirejs 帮你解决的是
模块间依赖问题
,和js代码异步加载
问题。但是 requirejs 并没有帮你解决
异步流程控制问题
而题主所遇到的就是典型的
异步流程控制问题
使用高阶函数
这种问题有很多解决方案,其中最简单的的方法就是
高阶函数
(js 是一个强大的函数式编程语言)利用
高阶函数
可以犀利的解决这个问题,但是高阶函数
就像 c 语言的指针。强大但是很容易让你头疼。可以使用社区中 async 模块,可以帮你轻松管理 异步流程。它完全使用 js 高阶函数实现。
前端安装模块:
bower install async
使用 Q (Promise/Deferred)
还有一种 解决方案 就是
Q
,Q 包含了Promise
实现,和Deferred
实现。使用 deferred 可以比较优雅的处理这个问题
Q
可以优雅的封装我们的异步代码,管理异步中的异常,著名 jQuery 类库 1.5 之后ajax部分使用 Promise 重写,流行的前端框架AngularJS
中的$q
就是一个 Promise 的实现,这种模式在 java中也有所使用。Chrome 第32个版本中内置了 Promise 类,来支持这个功能。 但是 IE 目前没有支持。
并不推荐使用浏览器自带的
Promise
。在前端,如果项目中,自带有 jquery 类库的话。
如果项目中没有jQuery的话,可以使用 q 模块, 还有类似的 when 模块。
bower install q
只有 2.5 KB了解更多 Promise, 传送门 链接描述
使用 generator (仅供尝鲜)
** chrome >= 39 支持, 在 nodejs > 0.11.x 支持**
是的 还要利用 高阶函数
配置好 requirejs
这里需要一个 叫
co
模块。bower install co
co 在 浏览器中依赖 setImmediate 模块,setImmediate 在 nodejs 中是原生
。function $sound_thunkify() { return $sound;}
这段为什么会这样。tj 称这个过程叫 trunkify 翻译过来叫做
块状化
你可以使用一个叫做
trunkify
的 模块bower install trunkify
Generator 的出现,并不是取代 Promise 模式,他们是互补的。
如果对这种方式感兴趣的话,可以看看 朴灵的文章 -> Generator 也许会有收获。
Promise技术可以帮到你,将模块内容定为promise对象即可回避null/undefine(想拿拿不到)和加载成功后不知道(拿到了又触发不下去)的问题
我也介绍一个吧
https://github.com/caolan/async
使用thenjs也可以这样的,而且比promise更加直观。
q也不错 习惯angular的$q