简体   繁体   English

如何处理嵌套的诺言?

[英]How to handle nested promises?

I'm fairly new to the promises concept, at least at creating them. 我对诺言概念相当陌生,至少在创建诺言方面。 I've read documentation how they work and I get how a promise works. 我阅读了文档,了解它们如何工作,并了解诺言的工作方式。 I also understand how you can trigger some callback when all promises are done, I just don't get it how to implement it in my code. 我也了解如何在完成所有诺言后触发一些回调,但我只是不知道如何在代码中实现它。

My code simplefied: 我的代码简化了:

function start_it_all(){
    return $cordovaSQLite.execute(db, "SELECT foo FROM bar").then(function(result) {
        return anotherFunction();
    });
}
function anotherFunction(){
     return $http.get('foo.php').then(function(){
        // Here I get some data
     });
 }

Both the $cordovaSQLite and the $http are async. $cordovaSQLite$http都是异步的。 I need to be able to do this: 我需要能够做到这一点:

start_it_all().then(function(){
   // Hide Loading animation (no further return data needed).
});

I understand that the .then() are the promise handlers, but as I currently have it, it returns just the promise of the query, I want the $http to give the promise. 我知道.then().then()处理程序,但是正如我目前拥有的那样,它只返回查询的Promise,我希望$http给出Promise。 At this point I get TypeError: Cannot read property 'then' of undefined on the start_it_all().then() 此时,我收到TypeError: Cannot read property 'then' of undefined start_it_all().then() TypeError: Cannot read property 'then' of undefined

Can anyone explain how to do that? 谁能解释该怎么做?

You don't have to nest those promises, you can do the following: 您不必nest这些承诺,可以执行以下操作:

function start_it_all(){
    return $cordovaSQLite.execute(db, "SELECT foo FROM bar")
    .then(function(result) {
        return $http.get('foo.php');
    })
    .then(function(){
            // Here I get some data
    });
}

Based on the comments in the original question, the .then method of $cordovaSQLite.execute seems not to be Promise/A+ compliant 根据原始问题中的评论, $cordovaSQLite.execute方法似乎不符合Promise / A +

to fix this, wrap $cordovaSQLite.execute(...) in Promise.resolve 要解决此问题,请在Promise.resolve包装$cordovaSQLite.execute(...)

function start_it_all(){
    return Promise.resolve($cordovaSQLite.execute(db, "SELECT foo FROM bar"))
    .then(function(result) {
        return $http.get('foo.php');
    })
    .then(function(){
            // Here I get some data
    });
}

and, now, based on comment and edited question 现在,基于评论和已编辑的问题

function start_it_all(){
    return Promise.resolve($cordovaSQLite.execute(db, "SELECT foo FROM bar"))
    .then(anotherFunction)
    .then(function(){
            // Here I get some data
    });
}

As pointed out by @LenilsondeCastro - in angular you can use $q.when above where I've used Promise.resolve 正如@LenilsondeCastro所指出的那样-在角度上,您可以在上面使用$q.when地方使用$q.when Promise.resolve

Make sure you return the promise at every level of the chain, and to return the data at the deepest level. 确保在链的每个级别上返回承诺,并在最深层上返回数据。 So write: 所以写:

    return $http.get('foo.php').then(function(){
        // Here I get some data
        return data;
    });

Edit: the above was written before you modified your question and added the return . 编辑:以上内容是在您修改问题并添加return之前编写的。

Then in the main call, you'd probably want to have access to the data, so add the argument: 然后在主调用中,您可能希望访问数据,因此添加参数:

start_it_all().then(function(data){
   // Hide Loading animation.
});

Error handling 错误处理

In comments you indicated you got the execute promise back, ... this might indicate an error preventing the HTTP request from being made. 在注释中,您指出您已收回execute承诺,...这可能表示错误,导致无法发出HTTP请求。

To be sure you are not running an undetected error condition, add the error handlers as well: 为确保您没有运行未检测到的错误情况,还添加错误处理程序:

function start_it_all(){
    return $cordovaSQLite.execute(db, "SELECT foo FROM bar").then(function(result) {
        return anotherFunction();
    }, function(err) {
        console.log('error in SQL query', err);
    });
}
function anotherFunction(){
     return $http.get('foo.php').then(function(){
        // Here I get some data
        return data;
     }, function(err){
        console.log('error occurred in HTTP request', err);
     });
 }

start_it_all().then(function(){
    // ...
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM