我有一个工作非常好的函数。我只是想根据承诺返回真或假。
//I want this function to return a simple true or false!!!
function isAppOnline() {
var is_connected = connectivityMonitor.isInternetConnected();
is_connected.then(function(result) {
console.log('INTERNET_CHECK_API : app online');//works fine
return true;//this is not being returned
}, function(error) {
console.log('INTERNET_CHECK_API : app offline');//works fine
return false;//this is not being returned
});
}
但是当我调用这个函数时,
is_online = isAppOnline();
is_online 总是定义。为什么函数不能返回一个简单的布尔值?
更新:
这就是我要做的:我只是想打开一个弹出通知用户,他是离线的。我在10秒后周期性地调用函数isAppOnline。这个函数已经在我的工厂中使用了一个promise。我不想让事情变得过于复杂,但对我来说,这个函数返回一个布尔值是很重要的,所以基于这个,我可以采取相应的行动。
编辑:适用于ES2017如果你是使用ES2017的幸运儿,那么你可以使用新的await/async关键字。它们非常出色,允许您编写读取同步的异步代码。(它仍然是幕后的承诺,只是把它们拆开了)。
function isOnline() {
return Promise.resolve(true);
}
async function Main() {
const online = await isOnline();
console.log(online);
}
Main();
fidle
因为它是异步的。你的isAppOnline
方法在你的promise解决之前返回。
我认为正在进行某种形式的AJAX调用来检查网络连接,因此它将不得不等待响应。JavaScript是单线程的,如果该线程锁定等待请求响应,那么它可能是同步的,整个JavaScript将暂停,直到它返回。不好。
所以如果你想让isAppOnline
的调用者知道结果,你必须有两个选项。要么给它一个回调,要么返回承诺(更好的选择)
function isAppOnline(cb) {
var is_connected = connectivityMonitor.isInternetConnected();
is_connected.then(function(result) {
console.log('INTERNET_CHECK_API : app online');//works fine
cb(true);
}, function(error) {
console.log('INTERNET_CHECK_API : app offline');//works fine
cb(false);
});
}
//better option
function isAppOnline() {
return connectivityMonitor.isInternetConnected().then(function(result) {
console.log('INTERNET_CHECK_API : app online');//works fine
return true;
}, function(error) {
console.log('INTERNET_CHECK_API : app offline');//works fine
return false;
});
}
//used as
isAppOnline().then(function (isOnline) {
console.log('Is it online?', isOnline);
});
Promise与简单语句的工作方式不同,因为它们可能稍后返回,因此您可能需要重新考虑程序流程以处理不同的初始和最终状态。
function isAppOnline() {
var is_connected = connectivityMonitor.isInternetConnected();
return is_connected.then(function(result) { // add return here to return the whole promise
console.log('INTERNET_CHECK_API : app online');//works fine
return; //this will resolve the promise returned
}, function(error) {
console.log('INTERNET_CHECK_API : app offline');//works fine
$q.reject(); // this will reject the promise returned
});
}
你将不得不处理调用控制器的状态变化(它可能在短时间内为假,然后变为真,等等)。你可以考虑使用加载状态来防止误导用户。
is_online = false;
isLoading = true;
isAppOnline().then(function() {
is_online = true;
}, function() {
is_online = false;
})
.finally(function(){
isLoading = false;
});
你的问题表明我们非常需要进一步探索Javascript的异步处理。我推荐阅读:如何从异步调用返回响应?
你可以实现一些技巧来强制一个方法同步返回,但是angular的构建方式几乎处处都遵守了承诺。如果你能给我们更多关于你想要完成的事情的背景信息,我们也许能帮助你以一种利用承诺本身的方式编写代码。
您可以尝试以下操作(这是未经测试的代码,因为您没有提供工作脚本):
function isAppOnline() {
var defer = $q.defer();
var is_connected = connectivityMonitor.isInternetConnected();
is_connected.then(function(result) {
console.log('INTERNET_CHECK_API : app online');//works fine
defer.resolve(true);
}, function(error) {
console.log('INTERNET_CHECK_API : app offline');//works fine
defer.resolve(false);
});
return defer.promise;
}
然后这样命名:
var is_online = false;
isAppOnline().then(function(data){
is_online = data;
});
或者,直接传递is_connected对象,这样可以更好地处理错误:
function isAppOnline() {
var defer = $q.defer();
var is_connected = connectivityMonitor.isInternetConnected();
is_connected.then(function(result) {
console.log('INTERNET_CHECK_API : app online');//works fine
defer.resolve(is_connected);
}, function(error) {
console.log('INTERNET_CHECK_API : app offline');//works fine
defer.reject();
});
return defer.promise;
}