我有一个标准的javascript对象,其原型扩展了一个.start()方法success,failure分别采用2个回调作为参数:和.此方法执行一些异步处理(它不是 AJAX),并根据此处理的结果调用成功或失败回调.
这是如何模式化的:
function MyObject() {
}
MyObject.prototype.start = function(successCallback, errorCallback) {
(function(s, e) {
window.setTimeout(function() {
if (Math.random() < 0.8) {
s();
} else {
e();
}
}, 2000);
})(successCallback, errorCallback);
}
Run Code Online (Sandbox Code Playgroud)
在方法内部执行的确切处理并不重要,只是它是异步和非阻塞的.我无法控制start方法完成处理的时间点.我也无法控制这种方法的原型和实现.
我控制的是success和failure回调.我应该提供它们.
现在我有一个这些对象的数组:
var arr = [ new MyObject(), new MyObject(), new MyObject() ];
Run Code Online (Sandbox Code Playgroud)
此数组中元素的顺序很重要.我需要.start()连续地在数组的每个元素上触发方法,但只在前一个元素完成后触发(即调用成功回调).如果发生错误(调用失败回调),我想停止执行,不再对数组的其余元素调用.start方法.
我可以通过使用递归函数来天真地实现它:
function doProcessing(array, index) {
array[index++].start(function() {
console.log('finished processing the ' + index + ' element');
if (index < …Run Code Online (Sandbox Code Playgroud) 我有一个简单的事件链:
我曾经只是链接这些函数,每个函数在完成后调用下一个函数.然而,它不是很明显(getColumnsFromMeta正在填充视图中的结果).因此,为了清晰和重复使用代码,我想重构这些JQuery Promises.我以前用过承诺.但是我如何连锁超过两个?getColumnsFromMeta ().then(loadSourceFromDatabase /*some arguments*/) //.then(renderList)?;
这是一个例子getColumnsFromMeta:
var getColumnsFromMeta = function(id)
{
var sql,
dfd;
dfd = $.Deferred();
var onSuccess = function(tx, result)
{
var columns = [];
for (var i = 0; i < result.rows.length; i++)
{
columns.push(result.rows.item(i).Column);
}
dfd.resolve(columns);
};
var onError = function(tx, error)
{
dfd.reject(error);
};
sql = "SELECT Column FROM Meta WHERE id = ?";
database.query(sql, [id], onSuccess, onError);
return dfd.promise();
};
Run Code Online (Sandbox Code Playgroud) 在执行函数之前是否可以"等待"多个事件?我知道可能用jQuery deferredobejcts $.when等待两个承诺来解决,但我想知道它是否可能只是简单的旧事件?
假设点击事件和自定义事件触发警报,例如:
$.when("click", "customEvent").then(function(){ alert("yay"); });
Run Code Online (Sandbox Code Playgroud) 我有三个函数我正在尝试运行,前两个正在做一些异步的东西,需要第三个使用的数据.我希望只有当1和2都完成时才会触发第三个函数.这是一般结构,但最终功能是在1和2结束前开始.
function run() {
var data1 = {};
var data2 = {};
$.when(first(), second()).done(constructData());
function first() {
var d = new $.Deferred();
//do a bunch of stuff async
data1 = {};
d.resolve();
}
function second() {
var d = new $.Deferred();
//do a bunch of stuff async
data2 = {};
d.resolve();
}
function constructData() {
//do stuff with data1 and data2
}
}
Run Code Online (Sandbox Code Playgroud)
答案是不立即调用构造数据
$.when(first(), second()).done(constructData);
Run Code Online (Sandbox Code Playgroud) 我正在使用jQuery .when()来包装一组promises,以便在所有promises都已解决后我可以执行一些操作.
$.when.apply($, requests).done(function () {
console.log(arguments); //it is an array like object which can be looped
var total = 0;
$.each(arguments, function (i, data) {
console.log(data); //data is the value returned by each of the ajax requests
total += data[0]; //if the result of the ajax request is a int value then
});
console.log(total)
});
Run Code Online (Sandbox Code Playgroud)
假设我希望在每个单独的承诺得到解决时得到通知,作为显示进度的一种方式.例如,如果requests有50个请求并且其中3个已经解决,我希望能够以6%显示进度条.有没有办法使用$.when它,以便它可以在不修改内部承诺及其进度事件的情况下返回整体进度?
我有一个Web应用程序,必须多次调用服务器.到目前为止,我有一个很长的嵌套回调链; 但我想用jQuery的when,then等功能.但是,在使用之后,我似乎无法再次运行then.
$
.when ($.get('pages/run-tool.html'))
.then (function (args)
{
// This works fine
alert(args);
$('#content').replaceWith (args);
$('#progress-bar').progressbar ({value: 0});
})
.then ($.get('pages/test.html'))
.done (function(args)
{
// This prints the same as the last call
alert (args);
});
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我猜它有一些范围问题,因为我可以看到get正在执行的第二个调用.使用两个不同的args变量没有帮助,因为传递给done函数的参数仍然是第一个get请求.
让我说我想以同步方式处理一些任务,所以我有这个功能:
function executePromiseQueueSync(queue){
var seed = $.Deferred(),
finalPromise;
finalPromise = _.reduce(queue, function(memo, promise){
return memo.then(function(){
return promise.funct.apply(null, promise.argmnt);
});
}, seed.promise());
seed.resolve();
return finalPromise;
}
Run Code Online (Sandbox Code Playgroud)
现在我可以用它来处理一些文件:
_.each(fileList, function(element, index, list){
_.each(element, function(el, idx, lst){
promisesQueue.push({funct: processFile, argmnt:[el, index + (len - fileList.length) ,len]});
});
});
Run Code Online (Sandbox Code Playgroud)
执行它并指出进度:
executePromiseQueueSync(promisesQueue).then(function(){
....
}, function(){
....
}).progress(function(msg, progress, name, index, status, desc){
console.log('progress');
});
Run Code Online (Sandbox Code Playgroud)
流程函数本身如下所示:
function processFile(file, index, size)
{
var dfd = new jQuery.Deferred();
if (file.name.match('(.*)\\.jpg'))
...
else if
...
else
$.when(processWrongFileType(file)).then(function(){
dfd.notify(...);
dfd.resolve(); …Run Code Online (Sandbox Code Playgroud) 经过几篇文章后,我逐渐了解了jQuery中的promise实现.但我不确定是否有任何版本的jQuery是否符合Promise/A.
我有两个从android调用的javascript函数.经过长时间的调试会议后,我意识到问题是由第二个函数在第一个函数完成之前被调用的事实引起的.我已经使用延迟等搜索了这些示例,但它们都依赖于另一个中的函数调用.
function FunctInit(someVarible){ //someVariable is sent from android, cannot call again from getResult
//init and fill screen
}
function getResult(){ //also getResult need to be called from android via button
//return some variables
}
Run Code Online (Sandbox Code Playgroud)
如何强制getResult等待FuncInit?有没有办法通过Javascript实现这一目标?
我有以下jquery延迟逻辑.
var $qCallA = callA();
var $qCallB = callB();
$.when($qCallA,$qCallB).then(function () {
$("#spinnerDiv").removeClass('spinner show');
});
function callA() {
return $.getJSON("/callA", function (data) {
if (data.status === "success") {
buildTable1(data);
}
});
}
function callB() {
return $.getJSON("/callB", function (data) {
if (data.status === "success") {
buildTable2(data);
}
});
}
Run Code Online (Sandbox Code Playgroud)
我希望根据后端json的响应为$ .getJSON调用返回false.例如,如果data.status =="失败",那么我想为getJSON返回"false".怎么做到这一点?
谢谢