在AngularJS或Javascript(浏览器)中等待异步数据
我正在用AngularJS为Odoo服务器编写一个服务包装器,它拥有服务器支持的所有方法,并在调用服务时返回一个延迟承诺。例如:在AngularJS或Javascript(浏览器)中等待异步数据,javascript,angularjs,async-await,openerp,Javascript,Angularjs,Async Await,Openerp,我正在用AngularJS为Odoo服务器编写一个服务包装器,它拥有服务器支持的所有方法,并在调用服务时返回一个延迟承诺。例如: $scope.runRPC = function(){ odooSvc.fields_get('res.users').then( function(result){ console.log(result); //return a list of users } ); } 然而,我需要它是同步
$scope.runRPC = function(){
odooSvc.fields_get('res.users').then(
function(result){
console.log(result); //return a list of users
}
);
}
然而,我需要它是同步的,这里有一个原因
在Odoo中,它有自己的JSON rpc API,它有几个相互依赖的方法
比如说,
search\u read:给你一个模型上所有东西的列表
fields\u get:为您提供模型具有的字段列表
还有更多
通常在一个正常工作的应用程序中,我们需要调用2个或更多的API方法来获得我们想要的最终数据。然而,因为在Java中,一切都是异步工作的,所以代码I映像将是嵌套的和复杂的
因此,当我进行每个API调用时,它们相互依赖。它看起来是这样的:
$scope.setLoginToContactEmail = function(){
odooSvc.search_read('res.users').then(
function(users){
for(var i=0; i < user.length; i++){
user = users[0];
login = user.login
partner_id = user.partner_id
odooSvc.read_model('res.partner', partner_id).then(
function(partner){
if(login === partner.email){
odooSvc.write_model('res.partner', partner_id, {email: login}).then(function(msg){
console.log(msg);
});
}
}
)
}
}
);
}
$scope.setLoginToContactEmail=function(){
odooSvc.search\u read('res.users')。然后(
功能(用户){
对于(变量i=0;i
Vs,如果我可以同步运行这些API,或者在继续另一个调用之前等待数据到达。这看起来更简单:
$scope.setLoginToContactEmail = function(){
var users = odooSvc.search_read('res.users');
for(var i=0; i < user.length; i++){
user = users[0];
login = user.login
partner_id = user.partner_id
partner = odooSvc.read_model('res.partner', partner_id);
if (login === partner.email){
odooSvc.write_model('res.partner', partner_id, {email: login});
}
}
}
$scope.setLoginToContactEmail=function(){
var users=odooSvc.search_read('res.users');
对于(变量i=0;i
请告知。谢谢。异步方法是JavaScript的强大功能,我们必须加以利用。原因是,如果任务需要很长时间才能执行,那么我们不必等待,同时可以让其他任务执行 我们可以看到它相对于UI的优势,在UI中,我们可以将耗时较长的任务放在回调中,并且可以避免UI变灰。 因此,我建议采用aync方法 但是你决定方法执行的方式并不是更好的方式 Angular为您提供了$q.when(method())。然后(successCallback(response));,通过它,只有当method()执行完成并且method()响应可用于进行另一个promise调用时,控制才会进入successCallback。这种方法将帮助您降低代码的复杂性,因为您试图创建一系列回调,而这在传统上是不正确的
$scope.setLoginToContactEmail = function(){
$q.when(searchRead()).then(function(res) {
modelRead(res);
});
}
function searchRead() {
odooSvc.search_read('res.users').then(
// @TODO
}
);
}
function modelRead(res) {
odooSvc.read_model('res.partner').then(
// @TODO
)
}
异步方法是JavaScript的强大功能,我们必须利用它。原因是,如果任务需要很长时间才能执行,那么我们不必等待,同时可以让其他任务执行 我们可以看到它相对于UI的优势,在UI中,我们可以将耗时较长的任务放在回调中,并且可以避免UI变灰。 因此,我建议采用aync方法 但是你决定方法执行的方式并不是更好的方式 Angular为您提供了$q.when(method())。然后(successCallback(response));,通过它,只有当method()执行完成并且method()响应可用于进行另一个promise调用时,控制才会进入successCallback。这种方法将帮助您降低代码的复杂性,因为您试图创建一系列回调,而这在传统上是不正确的
$scope.setLoginToContactEmail = function(){
$q.when(searchRead()).then(function(res) {
modelRead(res);
});
}
function searchRead() {
odooSvc.search_read('res.users').then(
// @TODO
}
);
}
function modelRead(res) {
odooSvc.read_model('res.partner').then(
// @TODO
)
}
异步比同步好 然而,回调可能会变得非常混乱,因此我们有承诺。然而,承诺也可能变得杂乱无章,尽管没有那么糟糕。Async await是获取看起来同步的异步代码的最佳方法,但您必须进行传输。这取决于您要使用多少工具 下面是我编写ES5代码的方法(在
之后不开始新的一行,然后(
,这会减少缩进,我还对for循环做了一些更改,因为我不确定您的意思):
这取决于您想要进行的传输量。就个人而言,我将采用ES6的一部分(let/const、解构、箭头函数、模板字符串、模块、unicode改进、扩展运算符/rest参数、改进的对象文字,以及可能的类文字),您最常使用的东西/不太难传输。也可以使用async await:它不是ES6或ES2016的一部分,但现在处于第3阶段,因此它非常稳定,并且它确实使异步代码更易于阅读。需要注意的是,您必须使用or传输新的ES6/ES2016/等功能,并为promis使用polyfilles(异步等待在内部使用)
TL;DR:如果你发现自己陷入了异步地狱,那么异步等待方案可能是最好的解决方案。异步优于同步 然而,回调可能会变得非常混乱,因此我们有承诺。然而,承诺也可能变得混乱,尽管没有那么糟糕。异步等待是获取看起来同步的异步代码的最佳方式,但您必须进行传输。这取决于您要使用多少工具 下面是我编写ES5代码的方法(在
之后不开始新的一行,然后(
,这会减少缩进,我还对for循环做了一些更改,因为我不确定您的意思):
这取决于你想做多少传输。就个人而言,我会采用ES6的一部分(let/const、destructuring、arrow函数等)
$scope.setLoginToContactEmail = async function () {
const users = await odooSvc.search_read('res.users')
for (let user of users) {
const { login, partner_id } = user
const partner = await odooSvc.read_model('res.partner', partner_id)
if (login === partner.email) {
const msg = await odooSvc.write_model('res.partner', partner_id, { email: login })
console.log(msg)
}
}
}
<body ng-app="app" ng-controller="AsyncController">
<p>{{ message }}</p>
</body>
angular.module('app', []).controller('AsyncController', ['$timeout', '$scope', async function ($timeout, $scope) {
$scope.message = 'no timeout';
$scope.message = await $timeout(() => 'timeout', 2000);
$scope.$apply();
}]);