在AngularJS或Javascript(浏览器)中等待异步数据

在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 } ); } 然而,我需要它是同步

我正在用AngularJS为Odoo服务器编写一个服务包装器,它拥有服务器支持的所有方法,并在调用服务时返回一个延迟承诺。例如:

$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();
}]);