【问题标题】:Handling page loading with Promises使用 Promises 处理页面加载
【发布时间】:2019-10-28 15:18:14
【问题描述】:

我有一个变量处理页面加载真假。如果所有数据都准备好了,加载图标会被隐藏并显示页面的其余部分,然后“加载”变量为“假”。

我运行多个函数从Promise.all() 的数据库中检索数据,以确保所有数据都准备就绪。

但是,变量更改和页面更改之间存在时间滞后。即使所有数据都准备好并且“加载”变量为“假”,显示页面的其余部分也需要大约 10 秒。

$scope.load = true;

function getData1(){
     return new Promise((resolve, reject) => {
         //this is http call from Customer Service
         Customer.getCustomers().then(function(data){   
             if (data.data.success) {
                $scope.customers = data.data.customers; 
                resolve(true);          
             } else {
                 reject(false);
             }
        })
     })
}
function getData2(){
     return new Promise((resolve, reject) => {
         //this is http call from Event Service
         Event.getEvents().then(function(data){   
             if (data.data.success) {
                 $scope.events = data.data.events; 
                 resolve(true);         
             } else {
               reject(false);
             }
         })
     })
}
.
.
.
Promise.all([getData1(), getData2(), getData3()])
    .then(results=>{
        $scope.load = false;            
})

如果我将$scope.load = false 放置在每个函数中,它可以解决,但将$scope.load = false 放置在所有函数中而不是仅放置一次Promise.all() 是没有意义的。

 function getData1(){
     return new Promise((resolve, reject) => {
         //this is http call from Customer Service
         Customer.getCustomers().then(function(data){   
             if (data.data.success) {
                $scope.customers = data.data.customers;
                $scope.load = false;
                resolve(true);          
             } else {
                 reject(false);
             }
        })
     })
}

谁能解释为什么在这种情况下会出现时间延迟?


我在函数中看不到任何需要 10 秒才能完成的循环或任何内容。当我将console.log(results[0]) console.log(results[1]) console.log(results[2]) 放在Promise.all() 中时,它立即表明承诺已解决。

【问题讨论】:

  • getData1() 立即无条件地调用自己时,这如何工作?你确定这是你的代码吗? getData1() 的最终版本没有这个递归调用。我想第一个是错的?或者你在哪里完成你的数据库工作?
  • @trincot 对不起,我的意思是来自服务的 http 调用,所以我改变了部分。 Customer.getCustomers() 和 Event.getEvents() 为 DB 完成这项工作,如果它们都成功,我想停止加载并显示页面的其余部分。
  • 控制台有错误吗?
  • 没有没有错误

标签: javascript angularjs promise


【解决方案1】:

在需要 10 秒才能完成的函数中,我看不到任何循环或任何内容。当我将console.log(results[0]) console.log(results[1]) console.log(results[2]) 放在Promise.all() 中时,它立即表明承诺已解决。

Promise.all() 创建的 ES6 Promise 未与 AngularJS 框架执行上下文集成。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等。

改用$q.all:

̶P̶r̶o̶m̶i̶s̶e̶.̶a̶l̶l̶(̶[̶g̶e̶t̶D̶a̶t̶a̶1̶(̶)̶,̶ ̶g̶e̶t̶D̶a̶t̶a̶2̶(̶)̶,̶ ̶g̶e̶t̶D̶a̶t̶a̶3̶(̶)̶]̶)̶
$q.all([getData1(), getData2(), getData3()])
    .then(results=>{
        $scope.load = false;            
})

同时避免使用 ES6 Promise 构造函数:

function getData1(){
    ̶r̶e̶t̶u̶r̶n̶ ̶n̶e̶w̶ ̶P̶r̶o̶m̶i̶s̶e̶(̶(̶r̶e̶s̶o̶l̶v̶e̶,̶ ̶r̶e̶j̶e̶c̶t̶)̶ ̶=̶>̶ ̶{̶
    //this is http call from Customer Service
    return Customer.getCustomers().then(function(response){   
        if (response.data.success) {
            $scope.customers = response.data.customers; 
            return $scope.customers;          
        } else {
            throw "getCustomers failed";
        }
    })
}

getCustomers() 函数已经返回了一个 Promise,因此没有必要构造一个未与 AngularJS 执行上下文及其摘要循环集成的 ES6 Promise。

【讨论】:

  • 是的,它与 $q.all 一起工作!!!非常感谢。你让我开心。
猜你喜欢
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多