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()