我正在使用 google maps api,这段代码异步返回地点列表。我怎样才能调用这个函数并让它在收集完所有数据后触发一些东西?到目前为止,这是我尝试过的 -
$.search = function(boxes) {
function findNextPlaces(place_results, searchIndex) {
var dfd = $.Deferred();
if (searchIndex < boxes.length) {
service.radarSearch({
bounds: boxes[searchIndex],
types: ["food"]
}, function (results, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
return dfd.reject("Request["+searchIndex+"] failed: "+status);
}
console.log( "bounds["+searchIndex+"] returns "+results.length+" results" );
for (var i = 0, result; result = results[i]; i++) {
var marker = createMarker(result);
place_results.push(result.reference); // marker?
}
});
return dfd.then(findNextPlaces);
} else {
return dfd.resolve(place_results).promise();
}
}
return findNextPlaces([], 0);
};
最佳答案
要回答标题所暗示的问题,“将回调转化为 promise ”,简单的答案是使用一个非常简单的“ promise 模式”(我的术语),其中 Deferred 的 .resolve() 方法被建立为回调:
带回调的原始调用:
obj.method(param1, param2, ... paramN, callbackFn);
转换后的调用,使用 Deferred 包装器:
$.Deferred(function(dfd) {
obj.method(param1, param2, ... paramN, dfd.resolve);
}).promise();
无论 obj.method 是否异步,这都可以完成。优点是您现在可以在同一代码块中或更典型地在分配或返回生成的 Promise 的其他地方使用 Deferreds/promises 的完整链式。
在这个问题的情况下,可以使用这种模式......
$.search = function(boxes, types) {
function findPlaces(box) {
var request = {
bounds: box,
types: types
};
//***********************
// Here's the promisifier
//***********************
return $.Deferred(function(dfd) {
service.radarSearch(request, dfd.resolve);
}).promise();
//***********************
//***********************
//***********************
}
function handleResults(results, status, searchIndex) {
var message, marker;
if (status != google.maps.places.PlacesServiceStatus.OK) {
message = "bounds[" + searchIndex + "] failed : " + status;
}
else {
message = "bounds[" + searchIndex + "] returns " + results.length + " results";
for (var i = 0, result; result = results[i]; i++) {
marker = createMarker(result);
place_Results.push(result.reference);
}
}
return message;
}
var place_Results = [],
p = $.when();//resolved starter promise
//This concise master routine comprises a loop to build a `.then()` chain.
$.each(boxes, function(i, box) {
p = p.then(function() {
return findPlaces(box).done(function(results, status) {
// This function's arguments are the same as the original callback's arguments.
var message = handleResults(results, status, i);
$('#side_bar').append($("<div/>").append(message));
});
});
});
//Now, chain a final `.then()` in order to make the private var `place_Results` available via the returned promise. For good measure, the `types` array is also repeated back.
return p.then(function() {
return {
types: types,
results: place_Results
};
});
};
$.search() 现在可以按如下方式使用:
$.search(boxes, ["food"]).done(function(obj) {
alert(obj.results.length + ' markers were a added for: "' + obj.types.join() + '"');
});
DEMO - 注意:由于 jQuery 1.8.3 对 jQuery.Deferred.then() 进行了重大修订,因此需要 jQuery 1.8.3+。
这并不完全等同于问题中的代码,但可能有助于诊断您报告的问题。特别是:
调整代码来执行您想要的操作应该足够简单。
关于javascript - 将回调变成 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21967065/
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
是否可以为单个ActiveRecord实例添加回调?作为进一步的限制,这是继续使用库,所以我无法控制该类(除了对其进行猴子修补)。这或多或少是我想做的:defdo_something_creazymessage=Message.newmessage.on_save_call:do_even_more_crazy_stuffenddefdo_even_more_crazy_stuff(message)puts"Message#{message}hasbeensaved!Hallelujah!"end 最佳答案 你可以通过在创建对象后立
我想写一点“Deprecate-It”库并经常使用“method_added”回调。但是现在我注意到在包含模块时不会触发此回调。是否有任何回调或变通方法,以便在某些内容包含到自身时通知类“Foobar”?用于演示的小Demo:#IncludingModulswon'ttriggermethod_addedcallbackmoduleInvisibleMethoddefinvisible"Youwon'tgetacallbackfromme"endendclassFoobardefself.method_added(m)puts"InstanceMethod:'#{m}'addedto'
我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan
我有一个模型Listingbelongs_to:user。或者,Userhas_many:listings。每个列表都有一个对其进行分类的类别字段(狗、猫等)。User还有一个名为is_premium的bool字段。这是我验证类别的方式...validates_format_of:category,:with=>/(dogs|cats|birds|tigers|lions|rhinos)/,:message=>'isincorrect'假设我只想让高级用户能够添加老虎、狮子和犀牛。我该怎么做?最好在before_save方法中执行此操作吗?before_save:premium_che
我有一个Ruby文件,我将它作为rubyfile.rb"parameters"运行。我更喜欢将它作为regtask参数运行,而不必每次都包含ruby和文件名。我希望它与ls处于同一级别。我将如何做到这一点? 最佳答案 编辑你的文件,确保这是第一行,这样你的系统就知道如何执行你的文件:#!/usr/bin/envruby接下来,更改文件的权限以使其可执行:chmoda+xfile.rb最后,重命名并将其移动到将要执行的位置,而无需编写其完整路径:mkdir-p~/binmvfile.rb~/bin/regtask(如果~/bin存在,
我有一个应用程序专门使用Facebook作为身份验证提供程序,并正确设置了生产模式的回调。为了让它工作,您需要为您的Facebook应用程序提供一个站点URL和一个用于回调的站点域,在我的例子中是http://appname.heroku.com和appname。heroku.com分别。问题是我的Controller设置为只允许经过身份验证的session,所以我无法在开发模式下查看我的应用程序,因为Facebook应用程序的域显然没有设置为本地主机。如何在不更改Facebook设置的情况下解决这个问题? 最佳答案 创建另一个域l
只是想知道是否有一种方法可以在Rails中进行条件回调。我知道您可以像这样进行条件验证:validates_uniqueness_of:email,:if=>(1==1)我经常在回调中做这样的事情:classLineItem稍微清理一下就好了。 最佳答案 classLineItem 关于ruby-on-rails-Rails模型中的条件回调?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/quest