这是我的基本情况:
function somePostThing() {
return $post("/someUrl").done(doSomething);
}
function doSomething(data) {
// do stuff with the data
}
var object = {};
object.deferred = somePostThing();
// A few cycles later, object.deferred may be resolved or unresolved
object.deferred.done(function () { /* ... */ });
Run Code Online (Sandbox Code Playgroud)
最后一行可能有效,也可能无效,因为done在已解析延迟对象的情况下不会触发.我希望能够做到这样的事情:
function doSomethingWithData(data) {
// do stuff
}
var value;
if (object.deferred.isResolved()) doSomethingWithData(object.deferred.value());
else object.deferred.done(doSomethingWithData);
Run Code Online (Sandbox Code Playgroud)
我如何获得已经解决的价值jQuery.Deferred()?
我正在设计一个包装我的REST API的JavaScript API.我通常希望避免大量冗长和混乱的嵌套回调,并且已经阅读了Deferred jQuery的优点.
让我们想象一下我的库'myLib',它代表人物对象和人物之间的遍历方式.它有一堆方法,比如'爸爸','老板','助手'等需要做一个ajax请求来查找一些数据并返回另一个相关的'people'对象.但我希望他们返回一个延迟对象,该对象也有myLib的方法,我可以链接在一起,编写真正简洁的简单代码,如下所示:
myLib('me').dad().boss().assistant(function(obj){
alert(obj.phone); // My dad's, bosses assistants phone number
}, function(){
alert('No such luck);
});
Run Code Online (Sandbox Code Playgroud)
这会创建一个'我'人物对象,然后进行第一次ajax调用以查找我的详细信息,然后使用该数据进行另一次调用以找出我的父母,然后再次找到我的老板,然后再找到另一位助手,然后最后,这传递给我的回调,我处理它.有点像jQuery的链式遍历方法,但异步.
在任何一点传递函数,但通常是最后一个方法,在解析链中的最后一个Deferred对象时将在内部调用.第二个函数是失败回调,如果链中的任何延迟对象被拒绝,则调用该函数.
我想我需要创建一个jQuery延迟对象,然后扩展它但不确定这是否是"最佳"方式.
那么实现我的极简主义API目标的最佳实践方法是什么?基本上我希望所有的方法名称在域问题名称空间中都是100%,并且没有被大量的'when','done','success'等污染.
是否有类似的清洁API的例子,我可以在某处模拟?
jQuery如何实现其Deferred对象,以便new运算符是可选的var x = $.Deferred();?
我目前有一个基本实现,捕获所有图像已加载但我不满意代码,可伸缩性和UI与viewModel之间的紧密耦合.
我有一个我已经在我的viewModel和bindingHandler之外声明的promises数组,以便每个人都可以访问它.bindingHandler会将每个未解析的promise推送到数组中,init函数将等待,直到数组收到所有已解析的promise.一旦发生这种情况,就会调用一个函数来为所有图像设置统一的高度.
这是UI:
<ul data-bind="foreach: movies">
<li>
<div class="image">
<img data-bind="imageLoad: { src: posters.Detailed, alt: title }"/>
</div>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
另一边:
function ViewModel() {
var self = this;
self.movies = ko.observableArray([]);
self.init = function(data) {
self.isLoading(true);
self.movies = ko.utils.arrayMap(data, function(item) {
return new robot.ko.models.Movie(item);
});
$.when.apply($, promises).done(function () {
robot.utils.setThumbnailHeight($('.thumbnails li'), function () {
self.isLoading(false);
});
});
};
}
ko.bindingHandlers.imageLoad = {
init: function(element, valueAccessor) {
var options = valueAccessor() || {};
var promise = $.Deferred();
var loadHandler = function() …Run Code Online (Sandbox Code Playgroud) 我有许多需要完成的异步任务,所以我使用的是promises.
我需要检测每个承诺何时被执行(解决和拒绝).在此之前我不能继续执行.
我使用的是这样的东西:
$.when(promise1, promise2, ...).always();
Run Code Online (Sandbox Code Playgroud)
但是这个代码是错误的,因为该when方法具有惰性求值,并且只要其中一个promise失败就会返回.因此,always只要其中一个承诺失败,回调也会运行.
我想在编码一个解决办法,但这种使用情况是如此普遍,也许有人已经做它已经,或者也许甚至还有这样做只使用jQuery的的一种方式(如果不是,这将是很好添加Promise.whenNonLazy或Promise.when(promise1, promise2, ..., false)在未来.
这可能吗?
如果从$.each循环调用jQuery延迟器,我似乎无法正常工作。
var deferreds = [],
ids = ['1234', '4321'],
users = [];
$.each(ids, function(i,v){
deferreds.push(
$.getJSON('api/users/'+v, function(i,v){
users.push(v.username);
})
);
});
$.when($, deferreds).done(function(){
console.log(users);
});
Run Code Online (Sandbox Code Playgroud) 在jQuery中我们可以做
$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
...
});
什么是角度相当的?我真的需要等待所有ajax调用完成然后做的事情.谢谢.
我无法找到delay或wait履行jQuery承诺.我在SO上找到了一个函数(使用jQuery.Deferred来避免嵌套的setTimeout回调):
function delay(time) {
return function () {
console.log("Delaying");
var ret = new $.Deferred();
setTimeout(function () {
ret.resolve();
}, time);
return ret;
};
}
Run Code Online (Sandbox Code Playgroud)
而且,这是我使用它的方式:
run: function () {
return $()
.promise()
.then(function () {
console.log("call together");
console.log("call together");
})
.then(delay(2000))
.then(function () {
console.log("call first");
})
.then(delay(2000))
.then(function () {
console.log("call second");
})
}
Run Code Online (Sandbox Code Playgroud)
我想扩展我可以编写的promise或deferred对象:
run: function () {
return $()
.promise()
.then(function () {
console.log("call together");
console.log("call together");
})
.delay(2000) …Run Code Online (Sandbox Code Playgroud) 我的Promise定义如下:
myFunc = function() {
$.getJSON("./rest/api/some/url", function(json, textStatus) {
console.log("AJAX call hit!");
});
};
$.when(myFunc()).then(function() {
console.log("Then block hit!");
});
Run Code Online (Sandbox Code Playgroud)
并在控制台中输出为:
Then block hit!
AJAX call hit!
Run Code Online (Sandbox Code Playgroud)
我需要第AJAX call hit!一个,然后是Then block hit!.
知道为什么会这样吗?我甚至试图实现一个自定义回调函数(我在Stackoverflow上找到的标准示例),它仍然无法正常工作.
我正在进行多个API调用,之后我想加载每个调用的组合结果:
$.when(
$.get(localAPI, data, function(response) {
globalStore.localShares = Number(response);
}),
$.get(facebookAPI, '', function(response){
globalStore.facebookShares = Number(response[0].share_count);
}),
$.getJSON(pinterestAPI, {url: url}).done(function(response){
globalStore.pinterestShares = Number(response.count);
})
).always(function(){
//Do stuff
});
Run Code Online (Sandbox Code Playgroud)
如果$.get调用失败,则$.always仍会执行回调函数.
但
如果只有一个$.get呼叫失败,则它会否定先前呼叫的操作.
因此,如果第一次调用失败,则globalStore返回两个项目.如果第一个调用成功但第二个调用失败,则globalStore返回只有一个项目.如果前两个调用成功但最后一个调用失败,则globalStore返回空.
有没有办法解决?
编辑:
是的,我试图$.when像这样处理失败:
$.when(
$.get(mu30_ajax_frontend.ajaxurl, data, function(response) {
globalStore.localShares = Number(response);
}).fail(function(){
globalStore.localShares = 0;
}),
$.get(facebookAPI, '', function(response){
globalStore.facebookShares = Number(response[0].share_count);
}).fail(function(){
globalStore.facebookShares = 0;
}),
$.getJSON(pinterestAPI, {url: url}).done(function(response){
globalStore.pinterestShares = Number(response.count);
}).fail(function(){ …Run Code Online (Sandbox Code Playgroud) jquery-deferred ×10
jquery ×9
javascript ×5
promise ×4
ajax ×3
angularjs ×1
asynchronous ×1
deferred ×1
knockout.js ×1
new-operator ×1