IF语句的控制流程&异步功能

时间:2014-05-29 20:17:27

标签: javascript node.js asynchronous structure

我的代码结构如下:

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

假设满足IF条件,代码执行'stuff',然后进入异步函数调用。假设等待异步函数调用完成后,是否可以简单地执行调用但是退出IF语句并在同一时间执行“更多东西”?

OR

它是否完成等待异步函数调用完成执行,然后继续使用'更多东西'作为普通的IF语句块。

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

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

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

6 个答案:

答案 0 :(得分: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
)

通过这种方式,您可以创建更易于维护的代码。一开始就抓住它并不容易,但试一试,会给你带来很多麻烦!

答案 1 :(得分:0)

  

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

不,那不是什么"异步"手段。重点是它没有等待。该功能将在未来的某个时间点运行并完成;执行流程立即继续到下一行。

答案 2 :(得分:0)

关于您给定的代码,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元素的颜色最初将设置为红色,但如果异步请求返回并成功响应,则您的{{ 1}}元素的颜色为黑色。这是一个非常简单且可能不切实际的例子,但它可以很容易地进行测试以确认是,异步调用将异步发生。

答案 3 :(得分:0)

像其他人说的那样你可以使用Promise,async.js,step.js等来控制流量。如果在启用--harmony的情况下使用最新版本的节点,也可以使用生成器。

答案 4 :(得分:0)

承诺,向您展示正确的方法。首先,如果您正在寻找条件,则是异步的。其次,您需要一个 full 示例。您必须修改AJAX请求的URL ,并设置一些服务器代码以提供响应。我将在结尾处提供一个 baseline PHP文件。

如此有效:如果我的if条件对于JavaScript解析器来说花费的时间太长怎么办? JavaScript使用Promise。我不会全力以赴,我的目标是提供一个基准。在脚本结尾处,您会注意到成功或失败级别。如果条件,该脚本需要 two 异步。另外,我将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);
?>

答案 5 :(得分:-1)

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

您不必复制/粘贴N次。只需将“more stuff”放入函数中,并将该函数传递给所有异步回调。回调可以在完成正常处理时调用“更多东西”功能。