我尝试调用的异步函数由DomOutline的onClick
属性定义。对于此示例,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()
};
答案 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?,这不是以承诺为中心,但仍然非常相关。