有没有人知道使用新的jQuery'promises/deferred object'模式而不是旧的jQuery样式ajax方法涉及标准的'成功'和'错误'回调所涉及的任何重大性能损失?
我知道向前推进我们现在没有太多选择,因为'延迟'对象现在内置在AJAX核心中,但只是想知道是否存在任何可测量的差异以及新的'promises'设计模式是否实际上比旧的更有效学校匿名函数回调?
亲切的问候,马克
我正在尝试获取jquery延迟工作,如下面的代码所示.
<script type="text/javascript">
var appUrls = {
GetDataUrl : '@Url.Action("GetData")'
};
function GetData1(){
return $.getJSON(appUrls.GetDataUrl, { Id: 1 });
}
function GetData2() {
return $.getJSON(appUrls.GetDataUrl, { Id: 2 });
}
$(function(){
$("#result").html("Getting Data1, Data2 .... ");
$.when(GetData1(), GetData2())
.then(function(result){
//The 'result' only contains the data from first request.
console.log(result);
$("#result").html("Completed GetData1, GetData2");
});
});
</script>
Run Code Online (Sandbox Code Playgroud)
两个调用完成后,我想提取两个调用返回的Json数据.但是,'result'对象只包含第一次调用返回的数据(GetData1)?如何在上面的'then'回调方法中获得两个调用的结果.
受到这个(优秀)讨论在javascript中使用Promises的启发,我试图找出如何使用Deferred将异步和非异步函数链接在一起,以避免在使用我的" 全局存储 "代码时支付回调税.
我有几个与此相关的问题,但我会在这里问他们,因为背景是一样的.
我无法解决的一件事是我如何能够推断出非异步的东西 - 也就是说,我如何获取一个值,将其包装在一个promise中,然后直接返回它?(a -> M<a>)
另外,我如何获取异步函数并将其包装,以便它直接返回结果,但包含在promise中?((a -> b) -> (a -> M<b>))
最后一个问题,对于monadic怪胎 - 这个函数有一个标准名称吗? [a] -> (a -> M<b>) -> M<[b]>
所以我在接受采访时被问到这个问题,但它提出了一个很好的用例.假设您有一堆数据源.你想找到第一个可用的并处理它而忽略其余的.
所以类似于:
var datasources = new Array("somedatabase1/pizza","somedatabase2/beer","somedatabase3/llama");
var dfds = new Array();
$.each(datasources,function(source){
dfds.push($.getJSON(source));
});
$.when(dfds).done(function(){alert("they are all done");});
Run Code Online (Sandbox Code Playgroud)
忽略我真的不认为什么时候接受一个数组(也许它).这当然会让它等到它们全部完成.我正在寻找一些代码,让它等到一个,其中任何一个完成,然后不用担心其他的.
我被告知它只能递归地工作.
我有以下代码$.getJSON在存储库中使用,以返回一些数据,然后由其他函数使用.
$.when(
repository.getUserDetails().done(dataPrimer.getUserDetails),
$.Deferred(
function (deferred) {
deferred.resolve();
}
)
).done(
function () {
repository.getUserPolicyTitles().done(dataPrimer.getUserPolicyTitles);
},
function () {
repository.getUserPage().done();
}
);
Run Code Online (Sandbox Code Playgroud)
这有效,但我需要从以下位置返回一个值:repository.getUserDetails().done(dataPrimer.getUserDetails)
可以用作参数:repository.getUserPage().done();
getUserDetails的dataPrimer模块目前如下所示:
var getUserDetails = function (jsonString) {
var object = parser.parse(jsonString);
userDetails.userName = object.user.userName;
userDetails.lastPolicyWorkedOn = object.user.lastPolicyWorkedOn;
return userDetails.lastPolicyWorkedOn;
}
Run Code Online (Sandbox Code Playgroud)
我尝试了一些事情,比如.pipe()没有快乐,并且想要确信我正在使用一个体面的方法,所以我正在寻找"最佳实践"的方式来返回参数并在repository.getUserPage()函数中使用它吗?
我正在尝试使用从中返回的承诺Backbone.model.save().实际上,根据规范,如果有效则返回一个promise,否则返回false.我想在将来deferred.done()和deferred.fail()电话中使用返回值,无论类型如何.像这样:
var promise = model.save();
$.when(promise).done(function() {
console.log('success!');
});
$.when(promise).fail(function() {
console.log('dang');
});
Run Code Online (Sandbox Code Playgroud)
但是,$.when()当通过非承诺火灾时,done()如上所述,如果模型无效,则会$.when(false).done()触发,并且您获得"成功!".
我知道我可以使用success和error属性save(),但是使用我的代码,done()以后应用多个函数是有利的.这就是承诺的力量.
所以,我留下:
var promise = model.save();
if (promise) {
$.when(promise).done(function() {
console.log('success!');
});
$.when(promise).fail(function() {
console.log('dang');
});
} else {
console.log('dang');
}
Run Code Online (Sandbox Code Playgroud)
我讨厌不干.
var promise = model.save();
var fail = function() {
console.log('dang');
};
if (promise) {
$.when(promise).done(function() {
console.log('success!');
});
$.when(promise).fail(function() {
fail();
});
} …Run Code Online (Sandbox Code Playgroud) 承诺/延期我是一个新手.对于成功和错误案例,是否有一个好的模式来处理人们可能希望短路承诺链的情况?在错误的情况下,我知道你可以链接.then(null, function(error) {})到最后并从任何先前的域中捕获错误,但是如果你想以更自定义的方式处理错误并终止怎么办?您是否会在先前的错误处理程序中指定错误的"类型"并通过新的承诺返回它,以便在最终的错误处理程序中处理或跳过?那么一个成功案例,你想要在链中更早地终止(只是有条件地解雇任何后来then的)?
我有这门课:
(function(){
"use strict";
var FileRead = function() {
this.init();
};
p.read = function(file) {
var fileReader = new FileReader();
var deferred = $.Deferred();
fileReader.onload = function(event) {
deferred.resolve(event.target.result);
};
fileReader.onerror = function() {
deferred.reject(this);
};
fileReader.readAsDataURL(file);
return deferred.promise();
};
lx.FileRead = FileRead;
}(window));
Run Code Online (Sandbox Code Playgroud)
该类在循环中调用:
var self = this;
$.each(files, function(index, file){
self.fileRead.read(file).done(function(fileB64){self.fileShow(file, fileB64, fileTemplate);});
});
Run Code Online (Sandbox Code Playgroud)
我的问题是,有没有办法在循环完成后调用一个方法,并且self.fileRead已经返回循环中的所有内容?
即使一个或多个延迟失败,我希望它调用该方法.
function1 = function(){
something.on('transitionend', function(){
// now function2 should run
});
}
function2 = function(){
alert('ok');
}
function1();
function2();
Run Code Online (Sandbox Code Playgroud)
所以我听说过jQuery的承诺.我会返回一个"延迟"对象,在事件处理程序中我会调用deferred.resolve();
但是如果我在那里有多个事件处理程序并且我只希望下一个函数在所有事件被触发时运行会发生什么?+我不喜欢将像"延迟"这样的外来东西引入代码的其他部分的想法.
有没有其他方法来检测function1是否已完成所有工作?
javascript jquery jquery-plugins jquery-deferred jquery-events
我正在使用通常的Deferred链接方法在jQuery中进行一系列顺序AJAX调用.第一个调用返回一个值列表,随后的调用将返回那些返回的列表条目.在第一次返回列表的调用之后,后续调用可以按任何顺序完成,但必须一次完成一次.所以这就是我使用的:
$.when(callWebService()).then(
function (data) {
var looper = $.Deferred().resolve(),
myList = JSON.parse(data);
for (var i in myList) {
(function (i) {
looper = looper.then(function () { // Success
return callWebService();
},
function (jqXHR, textStatus, errorThrown) { // Failure
if (checkIfContinuable(errorThrown) == true)
continueChain();
else
failWithTerribleError();
});
})(i);
}
});
Run Code Online (Sandbox Code Playgroud)
事实证明,后续调用有时可能会失败,但我仍然希望进行剩余的调用.在我的列表中,这就是这一点创造性伪代码的意图:
if (checkIfContinuable(errorThrown) == true)
continueChain();
else
failWithTerribleError();
Run Code Online (Sandbox Code Playgroud)
我怎么实现continueChain呢?似乎任何延迟的失败都会导致链的其余部分也失败.相反,我想记录错误并继续列表的其余部分.
jquery-deferred ×10
jquery ×8
javascript ×7
promise ×2
asynchronous ×1
backbone.js ×1
deferred ×1
monads ×1