为DomOutline事件处理程序添加承诺

时间:2014-12-25 02:13:00

标签: javascript dom asynchronous promise

我尝试调用的异步函数由DomOutlineonClick属性定义。对于此示例,domClickHandler类似于接收所选元素的回调。

    var iWantThis;

    var myDomOutline = DomOutline({
        onClick: domClickHandler,
        filter: false,
        stopOnClick: true,
        hideLabel: true
    });

    var domClickHandler = function(element){
        iWantThis = element
        console.log("I am the element you've selected: " + element);
    };

    myDomOutline.start();
    console.log("From the outside world: " + iWantThis);
    return iWantThis;

DomOutline.start()立即返回,domClickHandler是异步回调。因此,在此示例中,即使在选择元素之前,最后一个console.log也将返回undefined。我尝试在包含$.when()的函数上尝试DomOutline.start()以返回promise(),但它没有使异步调用同步。在这里使用promise的方法是什么,以便在选择DOM对象时返回它?

我宣传了回调,但我不确定这将如何帮助我实现数组同步返回iWantThis

var domClikcHandler= function(element){
        var dfd = $.Deferred();
        classifiedElements = __classifyChildrenElements(element);
        dfd.resolve(classifiedElements);
        dfd.then(function(e){
            console.log(e);
            iWanThis = e;
        });
        return dfd.promise()
    };

1 个答案:

答案 0 :(得分:1)

让我们一步一个脚印。

承诺是什么

承诺对价值概念的抽象 - 它代表价值+时间。您在其上执行的操作会排队,并且会在时机成熟时发生。

承诺以待处理开始,然后通过解决方案成为:

  • 履行 - 意味着可以使用和链接。
  • 拒绝 - 表示操作失败,您可以尝试从中恢复

在非jQuery和本机承诺的库中 - 转换过程以及处理程序的执行始终是异步。这是为了在可能异步的情况下防止竞争条件。

承诺不是什么

承诺不是事件发射器 - 您不能将承诺绑定到多次发生的事件,因为它代表单个值。表示多个值的promise的双重称为Observable。您无法将承诺绑定到点击事件。

承诺不是魔术 - 它通常用JavaScript实现,它不能将异步代码转换为同步代码,而它的then抽象了排序本身的概念 - 它不能没有语言支持'停止'异步操作的代码,以便需要其他语言工具,如生成器(ES6)或async / await(ES7)。对于大多数不想通过a compile step承诺的浏览器用户来说,可以让您的生活更轻松,但不会使异步代码同步。

一般来说,promises使用返回值和抛出异常,以便...返回值和抛出的异常。承诺使用单个值解析一次,就像一个值只有一个值一样,一旦获得它就不会改变。

如何使用承诺

在你的情况下,点击处理程序从根本上不能用promises建模 - 它需要一个名为observable的事件发射器。你对onBtnClick的看法很好。

对于ready事件 - 假设您promisified it correctly(调用$.when自己没有帮助),您需要链接到它:

 myDomOutline.start().then(function(){
     alert("Ready!");
 });

如果您想从外部访问它,那么承诺就会很好:

function startWithData(){
     var request = $.ajax(...);
     return myDomOutline.start().then(function(){ // note the return
         startAnimations();
         doAnotherThing();
         return request; // return the request
     });
}

startWithData().then(function(data){
    // ajax done and ready event fired
    // access data here
});

作为补充阅读,请参阅How to return the response from an AJAX call?,这不是以承诺为中心,但仍然非常相关。