Javascript 如何处理未来保存和更新承诺中所需的信息
我有一个保存到API的对象。API返回一个唯一标识符:id 当我使用保存时,我得到一个承诺,其中包括我的新API分配id 现在,用户可能需要执行其他操作,这些操作需要id。例如,重命名小部件并重新保存,或者添加指向其id的其他对象 什么是实际的和理想的直截了当的选择* *我读过的关于stackoverflow的其他建议建议使用“resolve”,如果此时我恢复到路由器,这将很好。但我现在不在 下面是一个简单的例子:Javascript 如何处理未来保存和更新承诺中所需的信息,javascript,angularjs,promise,Javascript,Angularjs,Promise,我有一个保存到API的对象。API返回一个唯一标识符:id 当我使用保存时,我得到一个承诺,其中包括我的新API分配id 现在,用户可能需要执行其他操作,这些操作需要id。例如,重命名小部件并重新保存,或者添加指向其id的其他对象 什么是实际的和理想的直截了当的选择* *我读过的关于stackoverflow的其他建议建议使用“resolve”,如果此时我恢复到路由器,这将很好。但我现在不在 下面是一个简单的例子: widget.saveThis = function() { if ('
widget.saveThis = function() {
if ('id' in this) {
this.put();
} else {
var _this = this;
rest.all('widgets').post(this).then(function(result) {
// Copy the new properties I have received to this object.
// ignore the methods from restangular.
for (var key in result) {
if (typeof(result[key]) != 'function')
_this[key] = result[key];
}
p.refresh();
});
}
};
如果连续两次推送save,我们可能会得到对象的两个副本。想象一下您有一个服务,您可以在其中进行API通信(可能通过REST
"use strict";
(function() {
var module = angular.module('myModule.service');
module.factory('myService', function($http, $q) {
return {
/**
* save and get
*/
saveAndGet: function(myObject) {
var deferred = $q.defer();
$http.post(getContextPath()+'/rs/saveObj', JSON.stringify{myObject})
.success( function(data) {
deferred.resolve(data);
})
.error(function(response) {
deferred.reject(response);
});
return deferred.promise;
}
}
});
})();
现在,假设您有一个控制器,等待保存完成:
"use strict";
(function() {
var module = angular.module('myModule.controller');
module.controller('MyController' , function($scope, myService) {
var myObj = //set it somehow
$scope.id; //needed for save the "new" id
myService.saveAndGet(myObj)
.then( function(result) {
// is called if no error occured
$scope.id = result.id;
)};
})();
然后想象一下你有了那个后端(比如java)
这将是解决您问题的一种方法。我们需要代码示例。通常,不可能用javascript“等待”异步操作完成;相反,您必须使用回调。我不知道您正在使用什么库来执行请求,但通常是类似于
promisse.then(回调)
或promisse.when的东西(回调)
。如果您不想阻止用户执行某些操作(如编辑),可以禁用“保存”按钮,然后在“then”函数中获得ID后再次启用该按钮。@JCx yes您还绝对应该指示您当前正在“加载”。如果下一个操作需要来自该调用的信息,则调用将需要时间。您的选项是:1)不要让他们做任何事情;2)让他们编辑,但在您获得数据之前阻止他们发送下一个请求。@Jcx然后告诉用户原因。装载指示器下方的禁用按钮应足够。如果您不这么认为,工具提示禁用按钮“我们需要多一点时间来处理您的最后一个请求,只需一秒钟!”saveAndGet实际上应该是返回$http.post(getContextPath()+'/rs/saveObj',JSON.stringify{myObject})
我没有想到这是一个选项。如果没有显示ID,只需出现后端错误,然后让用户和/或应用程序重试。但是如果保存失败,因为没有返回id,应用程序需要进入重试循环吗?和/或用户需要重试?@amg argh:是,这也是可能的,并且是一个有效的答案。我只是用我的方式,因为我在服务中做了一些其他的事情,无论成功与否。在您的解决方案中,您必须在控制器中执行我不希望执行的所有操作,因为它会破坏控制器代码。@JCx:如果您无法保存您的ID,并且后端出现错误,那么您应该在http post返回错误时编写自己的错误处理。此时,您可以通过对话框通知用户出了问题。请深入了解@JCx not true,创建一个新的承诺只是为了返回承诺的精确副本并不理想。如果您需要进行操作,您仍然应该返回原始承诺,因为它们是链接的return$http.post(“path”,obj)
@POST
@Path("saveObj")
@Produces({"application/json"})
public Response createProjectComment(MyObj obj) {
// do something and create myNewId
if (myNewId == null) {
return Response.ok("error").build();
}
return Response.ok(myNewId).build();
}