在Javascript中,在返回语句后执行语句。

8
window.onbeforeunload = function() {
    if (document.getElementById("parentpan").style.display == "block") {
        return "You are logged out.";
            Logout();
    }
};

我希望在return语句后调用logout()函数,这可能吗?


为什么你需要按照那个顺序? - Blender
11
在将某人注销之前,技术上返回“您已注销。”是在撒谎 :) - Hunter McMillen
1
你正在向用户返回一个带有确定/取消提示的“您已注销。”?onbeforeunload不像window.confirm()那样起作用。 - epascarello
13个回答

15

在return语句之后不能执行任何内容。

编辑:finally语句允许在return之后执行代码以进行清理。

(这是一个关于XY问题的很好的例子:你问了Y,但从未告诉我们你实际需要的X是什么。)


3
@Femaref:实际上,确实有一个。(finally - SLaks
@Femaref 你可能需要澄清一下;使用计时器、事件处理程序等,确实可以让你将代码放在一个函数中,在函数返回后按时间顺序执行。 - Stuart
@Stuart:这与我所写的不同 - 我明确写了“在返回语句之后”。你指定的所有内容都是函数的副作用,与返回语句本身无关。 - Femaref

10

最好的方法和最有效率的方法是try、catch和finally

在这里,catch是可选的

 `try{ 
     // do something
     return;
   } finally {
    // call function after return
   }`

https://youtu.be/Is_o_L-ZIS8 这对你有帮助。


7

return语句结束一个函数,它之后的代码将不会被执行。你可以这样做:

ret = "You are logged out.";
Logout();
return ret;

7
你需要执行异步地Logout。这可以通过使用JavaScript中的setTimeout函数轻松实现,正如其他人所说的那样。以下是我常用的异步调用函数的方法:
Function.prototype.async = function () {
    setTimeout.bind(null, this, 0).apply(null, arguments);
};

该方法会立即 (等待 0 毫秒后) 将函数调用推到事件循环中。因此,该函数在当前代码完成后执行 (对于您来说,这是在返回后)。下面是如何使用它的简单示例:

alert.async("This will be displayed later.");
alert("This will be displayed first.");

由于第一个 alert 是异步调用的,因此它将在第二次调用 alert 之后执行。只需在函数调用前加上 async 即可实现。以下是您需要执行的操作:

window.onbeforeunload = function () {
    if (document.getElementById("parentpan").style.display === "block") {
        Logout.async();
        return "You are logged out.";
    }
};

缺点是什么?由于该函数受事件循环阻塞,它可能永远没有机会执行(因此用户将永远不会注销)。这种情况可能会出现。当控制进入无限循环或由于阻塞 AJAX 请求而挂起时,通常会发生这种情况。
然而,好消息是,这种情况非常罕见。所以不用担心。只需像其他人建议的那样使用 setTimeout,您就可以做得很好。个人认为,在返回"You are logged out."消息之前应注销,但这是您的应用程序。
新年快乐。干杯!

1
一般来说,如果您希望在函数返回后执行某些操作,可以设置一个计时器:
function myFunction() {
    if (document.getElementById("parentpan").style.display == "block") {
        setTimeout(Logout, 50); // Logout will be called 50ms later
        return "You are logged out.";
    }
};

然而,正如评论中所指出的那样,对于onbeforeunload来说,这并不是一个好主意,因为如果页面先完成卸载,计时器事件将不会被触发。


大多数现代浏览器在页面加载时会终止超时并忽略它。基本上是一种竞争条件。 - epascarello
@epascarello - 你的意思是“...当页面卸载”时,对吧?而且,计时器不能依赖于作为页面卸载的一部分触发。 - broofa

1
大多数其他回答者都没有理解你在这里想要做什么。你想让 window.onbeforeunloadwindow.confirm() 一样起作用。没有办法在 onbeforeunload 事件中执行 ok 操作。
你需要在 onunload 上挂钩来执行该操作。
window.onbeforeunload = function () { 
    return "Your session will be logged out" 
};
window.onunload = function () { 
    logout(); 
}

问题在于现代浏览器会终止运行在卸载/离开页面之前的许多进程,以“加速”浏览器,因此如果是异步的,就会出现竞争条件。


感谢@Shmiddty修复了那个问题,我觉得我的早晨咖啡还没有起作用。 :) - epascarello

0
你可以使用 setTimeout 来实现这个功能。你的代码应该如下所示。
window.onbeforeunload = function() {
    if (document.getElementById("parentpan").style.display == "block") {
        setTimeout(function(){
            Logout();
        }, 0);
        return "You are logged out.";
    }
};

这将确保在返回语句之后执行Logout


0
如果您的项目中使用了jQuery,您可以使用延迟机制。您可以像这样为正在进行的任务返回promise对象:
function task() {

   var defered = $.Deferred();
   setTimeout(defered.resolve , 5000);
   return defered.promise();

}  

function task2() {

   var defered = $.Deferred();
   setTimeout(defered.resolve , 10000);
   return defered.promise();
}   

function run() {
     return $.when(task(),task2());
}

var promise = run();

promise.done(function(){        
      alert("All tasks has been completed");        
});

演示


0

返回意味着您正在从调用的函数执行中返回。当执行 return 语句时,系统会理解函数执行已经结束,并且它将从调用该函数的主程序切换。

在程序中,您可以在 return 之后看到一个语句。但是系统不会检查那个语句。


0

我找到了两种方法来解决这个问题。 第一种方法是如 Bhavsar Japan所述

1. 使用try, catch和finally的示例

const example1 = () => {
  try {
    return console.log('will execute first')
  } finally{
    console.log('will execute second')
  }
  return 'will never execute'
}

const main = () => {
  const message = example1();
  console.log(message)
}

main()

2. 使用 Promise.resolve 的示例

const example2 = () => {
  Promise.resolve()
    .then(() => console.log('will execute after return'));
  return 'will execute first'

}

const main = () => {
  const message = example2();
  console.log(message);
}

main();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接