在promise被解析/拒绝后返回一个布尔值



我有一个工作非常好的函数。我只是想根据承诺返回真或假。

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

相关内容

最新更新