Javascript,异步并返回到完全相同的地方

发布于 2024-11-13 03:17:57 字数 729 浏览 2 评论 0原文

我的输入是我可以预处理的javascript代码。

在某个函数中间的某个特定点,有一个令牌我需要用一些异步请求(例如异步AJAX请求)替换。

在运行时:当异步请求返回时(正在执行回调),我需要返回到执行异步调用之前代码中完全相同的位置(具有相同的上下文)。

有可能吗?有什么想法吗?

请注意,(1)我可以预处理并更改代码,但是我喜欢......
(2)令牌实际上可以在任何地方,在循环中或其他任何地方。(3)令牌仅代表异步调用的位置,我可以解析整个文档

此代码可能在浏览器上或通过节点运行。 Node.js

示例代码:

function input(num){
     num +=10;
     <token>
     return num;
}

会翻译成诸如更新:之类的东西

function input(num){
     num +=10;
     wait(async-request(...,callback));
     return num;
}

,在我读完你的答案后,这里有一个额外的问题, Javascript:同步到异步转换器库

My input is javascript code that I can pre-process..

at some specific point in the middle of some function there is a token that I need to replace with some async request(e.g. async AJAX request).

On runtime: When the async request is back (the callback is being executed) I need to return to exactly the same place(with the same context) in the code where I were before executing the async call.

Is it even possible? any ideas?

note that (1) I can pre process and change the code however I had like..
(2) the token can be practically anywhere, in a loop or anywhere else.. (3) the token just represents the location of the the async call, I can parse the entire document

This code might run on a browser or via node.js

Sample code:

function input(num){
     num +=10;
     <token>
     return num;
}

Would translate to some thing like

function input(num){
     num +=10;
     wait(async-request(...,callback));
     return num;
}

Update: After I read your answer here is an additional question,
Javascript: sync to async converter libs

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

白云悠悠 2024-11-20 03:17:57

有几个项目尝试使用延续将以同步模式编写的代码重写为异步代码。例如,您可能想看看:

https://github.com/Sage/streamlinejs

一些模式(循环、尝试/捕获)可能比简单的线性流带来更多挑战,但我很确定在一般情况下这是一个可解决的问题。不过,我认为您无法通过简单的令牌替换来完成此操作 - 您需要解析 javascript 并对其进行转换。

There are several projects that attempt to rewrite code written in a synchronous pattern into async code using continuations. E.g. you might want to take a look at:

https://github.com/Sage/streamlinejs

Some patterns (loops, try/catches) likely present more challenges than simple linear flow, but I'm pretty sure it's a solvable problem in the general case. I don't think you'll be able to do it with simple token replacement, though -- you'll need to parse the javascript and transform it.

囚我心虐我身 2024-11-20 03:17:57

为了最好地实现这一点,请将代码分为两部分。我们将整个事情称为函数 f,直到并包括异步调用的所有内容都是 F1(),而实现异步结果后需要发生的所有内容是F2()

您需要做的是执行F1(),它的最后一个命令是进行异步调用。 F1() 现已完成,应该将处理返回到 main。

但是,异步调用的回调应该 (1) 将传入数据处理为结构(或您想要的任何结构),然后 (2) 调用 F2() 提供此新数据。

这是异步的诅咒/美丽 - 在等待回复时您无法保留同步代码,因此您必须更改结构,以便在收到异步回复后调用依赖的代码片段。

根据您的示例进行更新:
由于异步,您也必须改变对返回数据和消费的思考方式。假设您的调用代码是:

var b=input(2);

中间有异步调用是不会飞的。相反,您需要类似的东西:(

var b;
getInput(2);

function getInput(num) {
  num+=10;
  async-request(...,/*callback=*/supplyNum);
}
function supplyNum(reply) {
  b=reply;
}

这是一个示例 - 我完全不建议使用全局变量,但希望您能明白这一点)。我跳过了如何处理 getInput 中的 num - 考虑到您正在等待 async-request ,大概它可以接收 num 作为参数,因此它的答案将是相关修改。您很可能只是举一个例子,但我认为我应该提到它;)

To best achieve this is to divide your code into two pieces. We'll call the whole thing function f, everything up to and including the async call is F1(), while everything that needs to happen once the async result is achieved is F2().

What you need to do is execute F1(), who's last command is to make the asynchronous call. F1() is now done and should return processing to main.

However the callback from the async call should (1) process the incoming data into a structure (or whatever you have in mind) and then (2) call F2() supplying this new data.

It's the curse/beauty of async - you cannot hold up the synchronous code while you wait for the reply so you have to change your structure such that dependent pieces of code are called once the async reply is received.

Update from your example:
Because of async you have to change your way of thinking on return data and consumption too. Say your calling code was:

var b=input(2);

That's not gonna fly with an async call in the middle. Instead you'd need something like:

var b;
getInput(2);

function getInput(num) {
  num+=10;
  async-request(...,/*callback=*/supplyNum);
}
function supplyNum(reply) {
  b=reply;
}

(this is an example - I totally don't recommend using global variables but you hopefully get the idea). I skipped over with what to do with num from getInput - given you're waiting for the async-request presumably it could receive num as an argument so it's answer would be a relevant modification. In all likelihood you're just giving an example, but thought I should mention it ;)

欢烬 2024-11-20 03:17:57

Javascript,异步并返回到完全相同的地方......

这称为同步代码,是异步的对立面。

您真正需要的是阻塞调用。

Javascript, go async and return to exactly the same place…

This is called synchronous code and is the antithesis to async.

Really what you need is a blocking call.

○闲身 2024-11-20 03:17:57

这完全未经测试,但你可以尝试这样的事情:

function sleep(delay)
{
    var start = new Date().getTime();
    while (new Date().getTime() < start + delay);
}


function waitforAsync(url, callback) {

  var done = false;

  var req = new XMLHttpRequest();
  req.open("GET", url, true)
  req.onreadystatechange = function() {
      if (req.readyState != 4) { return; }
      callback(req.responseText);
      done = true;
  };
  req.send(null);

  while (not done) {
      sleep(1000);
  }
}


function input(num){
    num +=10;
    waitforAsync(url, callback);
    return num;
 }

This is completely untested, but you could try something like this:

function sleep(delay)
{
    var start = new Date().getTime();
    while (new Date().getTime() < start + delay);
}


function waitforAsync(url, callback) {

  var done = false;

  var req = new XMLHttpRequest();
  req.open("GET", url, true)
  req.onreadystatechange = function() {
      if (req.readyState != 4) { return; }
      callback(req.responseText);
      done = true;
  };
  req.send(null);

  while (not done) {
      sleep(1000);
  }
}


function input(num){
    num +=10;
    waitforAsync(url, callback);
    return num;
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文