【问题标题】:Control flow of an IF statement & Asynchronous functionIF 语句和异步函数的控制流程
【发布时间】:2019-04-09 15:30:25
【问题描述】:

我的代码结构如下:

IF (something) {
..stuff
..Asynchronous Function Call
}
ELSE (something) {
..stuff
..Asynchronous Function Call
}
..more stuff

假设满足 IF 条件,代码执行“stuff”,然后转到异步函数调用。假设等待异步函数调用完成,调用是否简单但退出 IF 语句并同时执行“更多内容”?

它是否完成等待异步函数调用完成执行,然后像普通的 IF 语句块那样继续“更多内容”。

在前一种情况下,关于如何确保异步函数调用在退出 IF 块之前完成的任何建议?

** 注意,我在两个异步函数调用中都包含了更多内容,以确保调用在继续之前完成,但我觉得这是非常糟糕的编程,因为如果我有 50 个 ELIF,我将不得不复制粘贴该代码 50 次,而不是仅将其放在 IF 语句的末尾。

非常感谢您提供的任何帮助!

【问题讨论】:

  • 根据异步的定义,您的异步函数确实等待其他任何事情发生。它在完成时完成执行,可能是一毫秒,也可能是 4 小时。
  • 请勿编辑您的帖子以包括自我推销。这公然违反​​了网站范围的规则。当前有待修改以将其删除。

标签: javascript node.js asynchronous structure


【解决方案1】:

您可以使用 JavaScript Promises 轻松、轻松地解决这个问题。查看以下链接:

JavaScript Promises 的基本思想是使用可以按特定顺序执行的异步调用。像这样:

$.when(GET_PRODUCTS).then(
 IF_SUCCESS DO THIS
 ELSE DO THAT
).fail(
 SHOW MESSAGE
 CLEAN EVERYTHING BECAUSE SOMETHING WRONG HAPPENED
).done(
 CLEAN EVERYTHING BECAUSE EVERYTHING WENT OKAY
)

这样,您可以编写更易于维护的代码。刚开始不太容易掌握,但试一试,会省去很多麻烦!

【讨论】:

    【解决方案2】:

    它是否完成等待异步函数调用完成执行,

    不,这不是“异步”的意思。 while 点是它等待。该功能将在将来的某个时间运行并完成;执行流程立即继续到下一行。

    【讨论】:

      【解决方案3】:

      关于您给定的代码,more stuff 在异步函数发生时发生。它不等待异步函数返回结果。

      根据您的“node.js”标签,我假设您的问题是关于服务器上的异步调用。但是,您可以将该行为与客户端 AJAX 调用进行比较。

      假设你有这个:

      var nav = document.getElementById('nav');
      
      function async(params) {
          var xhr = new XMLHttpRequest();
      
          // set up your request
      
          xhr.onreadystatechange = function() {
              // some conditions, and then on success:
              nav.style.color = 'black';
          };
      
          xhr.open('GET', 'resource.php'+params, true);
      
          // send your request
      }
      
      if ( /* condition */ ) {
          async( /* some parameter */ );
      } else {
          nav.style.color = 'red';
      }
      

      如果您要运行上述代码,无论哪种方式,您的 #nav 元素的颜色将首先设置为红色,但如果异步请求返回成功响应,您的 #nav 元素的颜色将为黑色.这是一个非常微不足道且可能不切实际的示例,但可以很容易地对其进行测试以确认是的,异步调用将异步发生。

      【讨论】:

        【解决方案4】:

        就像其他人说的那样,您可以使用 Promises、async.js、step.js 等来控制流程。如果您使用启用了 --harmony 的最新版本的节点,您也可以使用生成器。

        【讨论】:

          【解决方案5】:

          承诺会向您展示正确的方式。如果条件是您正在寻找的,首先关闭异步。其次,您需要一个 full 示例。您必须修改 AJAX 请求的 URL 设置一些服务器代码来给您响应。我将在最后提供一个 baseline PHP 文件。

          如此有效:如果我的if 条件对 JavaScript 解析器来说花费的时间太长怎么办? JavaScript 使用承诺。我不会全力以赴,我的目标是提供一个基线。在脚本结束时,您会注意到成功或失败级别。此脚本需要 两个 异步 if 条件。此外,我将script 元素保留在它所属的head 元素中,而不是廉价/静态/脆弱。最后确保您更改 HTTP 查询并在服务器上确认它,无需生成冗余文件。浏览器兼容性很好,除了不支持 IE11 但是我只遇到了非常特定的用例 require 所以如果您正在考虑将此代码用于非技术受众,我强烈建议您重新考虑您的给定问题的初始方法。

          <head>
          <script defer="true" type="application/javascript">
          //<![CDATA[
          function request(method,url)
          {
           return new Promise(function(resolve, reject)
           {
            var req = new XMLHttpRequest();
            req.open(method,url);
            req.withCredentials = true;
            req.onerror = function() {reject(Error('Network error.'));};
            req.onload = function() {if (req.status == 200) {resolve(req.response);} else {reject(Error(new Object({'response':req.response,'status':req.statusText})));}};
            req.send();
           });
          }
          
          function aysn_if()
          {
           request('get','https://www.example.com/test.php?t=1').then(function(response)
           {
            console.log('Success, level one if!', response);
            request('get','https://www.example.com/test.php?t=2').then(function(response)
            {
            console.log('Success, level two if!', response);
            },
            function(error)
            {
             console.error('Failed, second level.', error);
            });
           },
           function(error)
           {
            console.error('Failed, first level.', error);
           });
          }
          
          document.addEventListener('DOMContentLoaded', function (e) {aysn_if();},false);
          //]]>
          </script>
          </head>
          

          PHP

          <?php
          header('Access-Control-Allow-Credentials: true');
          header('Access-Control-Allow-Origin: '.((isset($_SERVER['HTTP_ORIGIN'])) ? $_SERVER['HTTP_ORIGIN'] : '*'));
          //JUST for testing, don't send this stuff outside of test environments!
          ksort($_SERVER);
          print_r($_SERVER);
          ?>
          

          【讨论】:

            【解决方案6】:

            你的第一个选择就是发生什么。

            您不必复制/粘贴 N 次。只需将“更多内容”放入一个函数中,然后将该函数传递给所有异步回调。回调可以在完成正常处理后调用“更多内容”函数。

            【讨论】:

              猜你喜欢
              • 2022-01-03
              • 1970-01-01
              • 2013-07-12
              • 2023-01-20
              • 2023-04-09
              • 2012-09-04
              • 1970-01-01
              • 2023-01-08
              • 1970-01-01
              相关资源
              最近更新 更多