javascript - 将 "quiz"建模为异步 "long running process"

标签 javascript button asynchronous promise jquery-deferred

很多人将他们的应用程序建模为一长串回调,调用流程中的下一步。我正在努力避免这种情况。我正在做一个培训网站中弹出的“测验”。我使用 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 并没有真正得到响应(即使重命名,它也不会做任何事情,真的)。而且,要找到谁在“解析”该对象仍然有些困难。所以这似乎不是一个好的模式。

那么我如何才能将整个测验建模为一系列异步事件呢?将上面的代码添加到[此处]的第一个代码中是否会非常糟糕(我认为是的,因为它太嵌套了)。

处理这个想法的好模式是什么

  • 几个异步初始化步骤
  • 用户执行操作时等待时间较长
  • 几个异步结束步骤

更新 对于后代来说,这就是该序列的计算方式:

$.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               */
                    });
                });
            });
        });
    });

最佳答案

不,图案完全没问题。等待用户输入是一项异步任务,可以而且应该使用 Promise 对其进行建模。

The thing is, quiz_getResponses would really just create a deferred object and then an "I'm done" button somewhere in the code would resolve it. I don't like it because getResponses doesn't actually DO anything. And it would still be somewhat not straightforward to find who is "resolving" the object.

您的 quiz_getResponses 函数应创建显示按钮,并在其上安装点击监听器(或在如果您想将按钮放入 HTML 中,至少是后者)。它甚至可能在单击按钮后(或测验超时等)负责清理按钮。

事实上,创建一个全局延迟并让任意点击处理程序(或者实际上,任何东西)解析它是一种反模式。按钮代码不应位于“某处”,而应位于 quiz_getResponses 函数内。

关于javascript - 将 "quiz"建模为异步 "long running process",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26765324/

相关文章:

javascript - 具有多个下拉列表的 Angular 过滤器

javascript - 我现在如何保存计数器值或 "Textbox"值,以便刷新后它将保持在那里

iphone - 更改 UISearchBar/键盘搜索按钮标题

python - Python 中的 Raspberry Pi 异步/连续语音识别

javascript - 如何调整传单 map 的大小?

javascript - 如何制作自定义Facebook分享按钮?

java - 按住按钮可以平滑地增加速度更改值

C++:异步写内存

java - 如何在 'main' 线程上运行 DefaultMessageListenerContainer

javascript - 当我使用它时,jquery 单击绑定(bind)不起作用