许多人将他们的应用程序建模为一长串回调,这些回调称为流程的下一步。我试图避免这种情况。我正在进行一项在测试网站内弹出的“测验”。我正在使用when / then范例启动所有内容,我喜欢它的外观:
$.when(
quiz_getQuizData(courseId),
quiz_loadDependencies()
).then(function(){
quiz_prepareData();
$.when(
quiz_buildPage(target)
).then(function(){
quiz_initEventHandlers();
quiz_start();
[here?]
});
});
它清楚地表明,首先获得数据和依赖关系,然后准备数据并构建页面,然后初始化事件处理程序并开始测验。
如果我进一步扩展以使“测验”成为异步过程怎么办?目前,我有一个回调函数,当某个函数决定完成测验时会调用它。但是为了在一个地方展示测验的整个生命周期,也许我应该添加
$.when(
quiz_getResponses() /* <-- user takes 20 min to answer some questions*/
).then(function(){
$.when(
quiz_submit()
).then(function(){
quiz_finish();
callback();
});
});
问题是,quiz_getResponses实际上只是创建一个延迟对象,然后代码中某处的“我已完成”按钮将解析它,然后触发其余部分。
我不喜欢它,因为getResponses没有真正获得响应(甚至重命名,它不会做任何事情,真的)。而且,找到谁“解析”对象仍然有点不直接。所以它似乎不是一个好的模式。
那么我如何为整个测验建模一系列异步事件?将上面的代码添加到[here]的第一个代码(我想是这样,因为它太嵌套了)会不会很糟糕。
处理
的想法的好模式是什么更新 对后人来说,这就是序列的实现方式:
$.when(
quiz_getQuizData(quizOptions['courseId']),/* submit courseId, wait for quiz data (questions, choices) */
quiz_loadDependencies() /* wait for yepnope to load javascript and css dependencies */
).then(function(){
quiz_prepareData(); /* build object for rendering quiz template */
$.when(
quiz_buildPage(targetSelector) /* wait for template, render page into target */
).then(function(){
quiz_initEventHandlers(); /* add handlers to click events */
quiz_start(); /* do any final preparations, show the quiz */
$.when(
quiz_getResponses() /* wait for user to answer questions (or time run out) */
).then(function(){
$.when(
quiz_getResults() /* submit responses, wait for results */
).then(function(){
$.when(
quiz_showResults() /* show results, wait for user to close */
).then(function(){
var result=quiz_finish(); /* do any final operations, hide and destroy the quiz */
callback(result); /* notify page that quiz is over, send result */
});
});
});
});
});
答案 0 :(得分:1)
不,模式完全没问题。等待用户输入是一个异步任务,可以 - 而且应该 - 使用promise建模。
问题是,quiz_getResponses实际上只是创建一个延迟对象,然后代码中某处的“我已完成”按钮将解析它。我不喜欢它因为getResponses实际上没有做任何事情。找到谁正在“解决”这个对象仍然有点不直接。
您的quiz_getResponses
功能应创建并显示按钮并在其上安装点击监听器(或至少后者)如果你想把按钮放在你的HTML中)。它甚至可以在点击按钮后清理按钮(或测验超时等)。
确实,创建一个全局延迟并让任意点击处理程序(或实际上,任何东西)解决它是一个反模式。按钮代码不应该是“某处”,而是在quiz_getResponses
函数内。