Javascript 如何处理嵌套承诺?

Javascript 如何处理嵌套承诺?,javascript,angularjs,ionic-framework,promise,angular-promise,Javascript,Angularjs,Ionic Framework,Promise,Angular Promise,我对承诺的概念相当陌生,至少是在创造它们。我已经阅读了它们如何工作的文档,并且了解了承诺是如何工作的。我也理解当所有的承诺都完成时,如何触发一些回调,我只是不知道如何在我的代码中实现它 我的代码简化了: function start_it_all(){ return $cordovaSQLite.execute(db, "SELECT foo FROM bar").then(function(result) { return anotherFunction();

我对承诺的概念相当陌生,至少是在创造它们。我已经阅读了它们如何工作的文档,并且了解了承诺是如何工作的。我也理解当所有的承诺都完成时,如何触发一些回调,我只是不知道如何在我的代码中实现它

我的代码简化了:

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
     });
 }
$cordovaSQLite
$http
都是异步的。我需要能够做到这一点:

start_it_all().then(function(){
   // Hide Loading animation (no further return data needed).
});
我知道
.then()
是承诺处理程序,但就我目前的情况而言,它只返回查询的承诺,我希望
$http
给出承诺。此时,我得到
TypeError:无法读取
start\it\u all()上未定义的
的属性“then”。then()

有人能解释一下如何做到这一点吗?

确保在链的每一级都返回承诺,并在最深层次返回数据。所以写下:

    return $http.get('foo.php').then(function(){
        // Here I get some data
        return data;
    });
编辑:以上内容是在您修改问题并添加
返回之前编写的

然后在main调用中,您可能希望访问数据,因此添加参数:

start_it_all().then(function(data){
   // Hide Loading animation.
});
错误处理 在您的评论中,您指出您得到了
execute
承诺。。。这可能表示阻止HTTP请求的错误

为确保您没有运行未检测到的错误情况,请同时添加错误处理程序:

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(){
    // ...
});
确保在链的每个级别都返回承诺,并在最深层次返回数据。所以写下:

    return $http.get('foo.php').then(function(){
        // Here I get some data
        return data;
    });
编辑:以上内容是在您修改问题并添加
返回之前编写的

然后在main调用中,您可能希望访问数据,因此添加参数:

start_it_all().then(function(data){
   // Hide Loading animation.
});
错误处理 在您的评论中,您指出您得到了
execute
承诺。。。这可能表示阻止HTTP请求的错误

为确保您没有运行未检测到的错误情况,请同时添加错误处理程序:

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(){
    // ...
});

您不必
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
    });
}
根据原始问题中的注释,
$cordovaSQLite.execute
的.then方法似乎不符合Promise/A+的要求

要解决此问题,请在
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
    });
}
现在,根据评论和编辑的问题

function start_it_all(){
    return Promise.resolve($cordovaSQLite.execute(db, "SELECT foo FROM bar"))
    .then(anotherFunction)
    .then(function(){
            // Here I get some data
    });
}
正如@LenilsondeCastro所指出的,在angular中,你可以使用
$q.when
在上面我使用的
Promise.resolve

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
    });
}

您不必
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
    });
}
根据原始问题中的注释,
$cordovaSQLite.execute
的.then方法似乎不符合Promise/A+的要求

要解决此问题,请在
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
    });
}
现在,根据评论和编辑的问题

function start_it_all(){
    return Promise.resolve($cordovaSQLite.execute(db, "SELECT foo FROM bar"))
    .then(anotherFunction)
    .then(function(){
            // Here I get some data
    });
}
正如@LenilsondeCastro所指出的,在angular中,你可以使用
$q.when
在上面我使用的
Promise.resolve

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
    });
}

我已经将它添加到了我的示例中,但它仍然会导致
TypeError:cannotreadproperty'then',of undefined
。你确定这是路吗?因为如果是这样的话,我必须检查代码的其他部分:)我确信这一点。在哪个
then
上出现错误?在$http PROMITE回调中添加一个响应参数:
then(函数(响应){return response.data;})如果“There I get some data”中的代码是synchronus,您不需要严格地返回任何内容(与以任何方式返回未定义的内容相同)-事实上,此代码位于then回调中,这意味着它将是最终从中返回的承诺。然后,确实如此,但数据将丢失,除非它存储在(更多)全局变量中,这不是很好。我已经将它添加到了我的示例中,但它仍然会导致
TypeError:cannotreadproperty'then',of undefined
。你确定这是路吗?因为如果是这样的话,我必须检查代码的其他部分:)我确信这一点。在哪个
then
上出现错误?在$http PROMITE回调中添加一个响应参数:
then(函数(响应){return response.data;})如果“There I get some data”中的代码是synchronus,您不需要严格地返回任何内容(与以任何方式返回未定义的内容相同)-事实上,此代码位于then回调中,这意味着它将是最终从中返回的承诺。然后,确实如此,但数据将丢失,除非它存储在(更多)全局变量中,这不是很好。我怀疑有什么问题-在我展开之前,请尝试
返回Promise.resolve($cordovaSQLite.execute(db,“从条形图中选择foo”)。然后(
等-即在
Promise.resolve()中包装
$cordovaSQLite.execute
返回的Promise
-看起来很愚蠢,但是,请原谅我:pI已将查询包装在一个
承诺中。resolve()
,解决了它。看来
$cordovaSQLite.execute
返回的承诺并不是一个很好的承诺-以前在其他一些图书馆中看到过类似的问题我已经发布了答案,答案也是“取消嵌套”你的代码-应该有效,给它一个goI怀疑什么-在我扩展它之前,尝试
返回承诺.resolve($cordovaSQLite.execute(db,“SELECT foo FROM bar”))。然后(
等-即在
承诺.resolve()中包装
$cordovaSQLite.execute
返回的承诺
-看起来很愚蠢,但是,请原谅我:pI已将查询包装在一个
承诺中。resolve()
,解决了它。看来
$cordovaSQLite.execute
返回的承诺并不是一个很好的承诺-以前在其他一些图书馆中看到过类似的问题我已经发布了答案,答案也是“取消嵌套”你的代码-应该有效,给它一个goI我不认为我能给出你的确切答案,因为
start\u it\u all()