我目前正在尝试使用HTML5 FileAPI构建文件上传器.如果文件是图像,则文件上载器应该处理多个文件并显示图像预览.
由于FileReader类异步工作,我想等到所有文件都被读取.因此我使用Deferreds.
读取文件的方法返回一个promise.另一种方法遍历所有文件并将所有promises推送到数组中.然后,我将所有promises添加到我的数组后应用then()方法.
现在我的问题.因为then()方法只被调用一次,所以我得到了所有的承诺.我没有机会处理每一个承诺.我想要做的是,一旦它们全部存在并且返回结果,就循环我所有的承诺.
这是我的FileProcessor对象
read: function(file) {
var reader = new FileReader();
var deferred = $.Deferred();
reader.onload = function(event){
deferred.resolve(event.target.result);
};
reader.onerror = function() {
deferred.reject(this);
}
if(/^image/.test(file.type))
reader.readAsDataURL(file);
return deferred.promise();
},
Run Code Online (Sandbox Code Playgroud)
这里是FileManager对象的handleFileSelect()方法,它应该调用FileProcessor.read()方法.
handleFileSelect: function(e){
var $fileList = $('#file-list');
var files = e.target.files;
var promises = []; //Promises are going to be stored here
var filestring = '';
var processedFile;
// Loop trough all selected files
for(var i = 0; i < …Run Code Online (Sandbox Code Playgroud) 我有一系列函数调用并使用async.waterfall.它就像一个魅力.但我想用jQuery Deferred做到这一点.如何转换我的代码?
jQuery站点的例子是这样的.两个结果都传递给done函数:
$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
// a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively.
// Each argument is an array with the following structure: [ data, statusText, jqXHR ]
var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
if ( /Whip It/.test( data ) ) {
alert( "We got …Run Code Online (Sandbox Code Playgroud) 我目前在我面前有一个非常棒的if-then-else循环,它首先从web服务获得多个cantinas.然后它会获得所有可用餐点(每个菜单)和所有可用的配菜(每个菜单).对于每一餐和两餐,然后检查所有添加剂并聚集它们.
最后,我有多种菜单,包括餐点,配菜和所有添加剂.
以下流程图显示了该过程:

我想美化代码,并希望使用jQuery的promises - 但我无法弄清楚如何做到这一点,因为我必须在a then之后堆叠when(至少我认为,也许我必须resolve?).以下是我最好的尝试:
//this totally does not work at all, but you get the idea what I want to do
Menus.getCantinas()
.when(Menus.getMeals(cantinas), Menus.getSides(cantinas)) //when doesn't exist here, neither does cantinas
.then(Menus.getAdditives(meals, sides) //also throws errors as meals and sides does not exist
.done(function(cantinas, meals, sides, additives) { //more errors for the people
Menus.cantinas = cantinas;
Menus.meals = meals;
Menus.sides = sides;
Menus.additives = additives;
//... some html stuff to build …Run Code Online (Sandbox Code Playgroud) 我阅读了关于使用jQuery Deferred的这个问题的最佳答案.
我正在遍历一系列ID.对于每个ID,我需要从ajax请求获取与之相关的数据,或者如果ajax请求之前已成功返回数据,则需要从缓存中获取数据.
在每个循环中,我使用$ .when()来观察getData()是否在处理该ID之前从缓存或成功的ajax调用返回一些内容.目前的问题是ID处理无论如何都要继续进行,而不必等待getData()的ajax成功.
一些伪代码:
var IDs = ["1", "2", "1", "3", "1"];
//ID "1" is repeated
//data for "1" should should require ajax get the first time
//subsequent processing should get data for "1" from dataCache
var dataCache = [];
function getData(ID){
if (/*data for ID in dataCache*/){
//return data pertaining to ID from dataCache
} else {
return $.getJSON("returnJSONDataByID/" + ID, function(resp){
//push resp data to dataCache
})
}
}
for (/*each item i …Run Code Online (Sandbox Code Playgroud) 为什么done()语句下的代码在被调用的另外3个函数之前执行when()?它会立即发生.我以为什么时候用来排队功能和完成用来执行什么时候代码是什么时候完成...
$(document).on('click', '.ajax', function() {
$.when(func1('<p>first</p>'), func2('<p>second</p>'), func3('<p>third</p>')).done(function() {
$('body').append('all done');
});
});
function func1(first) {
var t = setTimeout(function() {
$('body').append(first);
}, 800);
return "success";
}
function func2(second) {
var t = setTimeout(function() {
$('body').append(second);
}, 2700);
return "success";
}
function func3(third) {
var t = setTimeout(function() {
$('body').append(third);
}, 200);
return "success";
}?
Run Code Online (Sandbox Code Playgroud)
我有以下代码和一个模块
var def = $.Deferred();
$.getJSON("http://localhost:62588/api/Values/getXMLData")
.done(function(json){
def.resolve($.parseJSON(json));
});
return def;
Run Code Online (Sandbox Code Playgroud)
然后,我必须从另一个模块调用它,以便在调用处理返回的数据之前完成.
repository.getUserPolicies().done(function (userPolicies) {
process(userPolicies);
});
Run Code Online (Sandbox Code Playgroud)
这很好用但我还不太明白延迟对象是如何工作的.
我已经读过你可以使用getJSON的延迟对象,但不确定这是否正是我在这里做的?
我想知道这种方法有什么缺点吗?
可以更优雅地完成吗?
谢谢
我发现各种Deferred/promise库的文档通常涵盖非常简单的用例,例如链接1或2个函数/方法,并导致解决或拒绝成功或错误.
然而,当涉及到更复杂的用例(5个以上的函数/方法链;嵌套的Deferreds;从其他Deferreds中返回promise)时,我空手而归并变得非常沮丧.
比方说,我有一个包含2个嵌套函数的函数.每个子函数都返回一个promise,我希望父函数返回子函数的成功/失败结果:
var saveUser = function(user) {
var saveNewUser = function(user) {
var deferred = when.defer();
user.save(function (err) {
if (err) {
deferred.reject();
}
else {
// forcing a rejection here for testing purposes
deferred.reject(6);
}
});
return deferred.promise;
}
var supplyUserCollections = function() {
var deferred = when.defer();
deferred.reject();
return deferred.promise;
}
return saveNewUser(user).then(supplyUserCollections(), function() {
console.log('failed to save new user');
}).then(function(data) {
console.log('succeeded to do everything');
}, function() {
console.log('failed to seed new user collections');
});
} …Run Code Online (Sandbox Code Playgroud) 我有代码需要等待可变数量的服务器响应以及通过requireJS加载几个javascript模块.
我想利用jQuery的when.apply.不幸的是,我的代码的.then()部分总是在我的任何回调之前执行.
以下是我的代码摘要:
// load module func
function loadRequireJsModule(arg, callback) {
require([arg], callback);
}
// get layer info from server func
function getLayerInfoFromServer(arg, callback) {
var layerInfoListener = new DataLayer([arg]);
layerInfoListener.addRetrievedCallback(callback);
layerInfoListener.retrieveLayerInfo();
}
tasks.push( $.Deferred( function() {
loadRequireJsModule( "./" + layerJSON.type, function( module ) {
layer.controller = module;
});
}));
for (i=0; i<layerJSON.views.length; i++) {
layer.views[i] = {};
// get renderer class from require.js
tasks.push( $.Deferred( function() {
loadRequireJsModule( "./impl/" + layerJSON.views[i].renderer, function( index ){
return function( module ) { …Run Code Online (Sandbox Code Playgroud) 我想知道,如果有办法让jQuery Deferred使用Google Geocoder.我尝试过类似的东西:
// ...
_geocoder: function( address ) {
if ( !this.props.geocoder ) {
this.props.geocoder = new google.maps.Geocoder();
}
var deferred = $.Deferred(),
geocoder;
geocoder = this.props.geocoder.geocode( { 'address': address }, function( results, status ) {
if ( status === google.maps.GeocoderStatus.OK ) {
deferred.resolve({
lat: results[ 0 ].geometry.location.k,
lng: results[ 0 ].geometry.location.A
});
} else {
deferred.reject();
}
return deferred.promise();
});
$.when( geocoder() ).then(
function( data ) {
alert( status );
},
function() {
alert( "Defer rejected" );
} …Run Code Online (Sandbox Code Playgroud) 我有一个同步的方法foo(param).
我希望可以自由地调用foo(param)而不执行实际的foo()调用,直到稍后的特定事件.
它似乎是延迟/承诺的一个很好的候选者,但我必须做错事,因为超时没有任何影响.
log方法是否应该返回promise?
var log = function(message) {
$('#log').append('<p>' + message + '</p>');
};
$(function() {
var q = new $.Deferred();
q.then(log("1"));
q.then(log("2"));
q.then(log("3"));
q.then(log("4"));
q.then(log("5"));
q.then(log("6"));
q.then(log("7"));
setTimeout(function(){
q.resolve();
}, 10000);
});Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="log"></div>Run Code Online (Sandbox Code Playgroud)
我想包装$.ajax().done()一个单独的类,其中包括针对模式验证JSON响应.
示例调用可能如下所示:
myService.get("/api/people").done(function(people) {
// at this point I'm certain the data in people is valid
template.render(people);
}).catch(function() {
// this happens if validation of people failed, even if the request itself was successfull
console.log("empty json or validation failed");
});
Run Code Online (Sandbox Code Playgroud)
成功回调函数是传入的done(),但是只应在私有函数中执行(_validate(data, schema))返回true).不太优雅的版本可能如下所示:
myService.get("api/people", successCallback, errorCallback);
Run Code Online (Sandbox Code Playgroud)
我想$.ajax()直接公开内部的Deferred方法.这可能吗?
鉴于这种模式
someArray.reduce(function(p, item) {
return p.then(function() {
return someFunction(item);
});
}, $.Deferred().resolve()).then(function() {
// all done here
// access accumulated fulfilled , rejected `Promise` values
}, function err() {
});
Run Code Online (Sandbox Code Playgroud)
什么方法可以将已完成的,被拒绝的Promise对象的累积值返回到.then(fulfilled)调用后的数组.reduce()?
function someFunction(index) {
console.log("someFunction called, index = " + index);
var $deferred = $.Deferred();
window.setTimeout(function() {
$deferred.resolve();
}, 2000);
return $deferred.promise();
}
var someArray = [1,2,3,4,5];
someArray.reduce(function(p, item) {
return p.then(function() {
return someFunction(item);
});
}, $.Deferred().resolve()).then(function(data) {
// all done here
console.log(data, …Run Code Online (Sandbox Code Playgroud)jquery-deferred ×12
javascript ×11
jquery ×8
promise ×5
asynchronous ×3
deferred ×2
ajax ×1
arrays ×1
chaining ×1
node.js ×1