什么时候实际调用函数?我该如何控制它?

时间:2018-02-22 22:31:52

标签: javascript php jquery function asynchronous

JS新手在这里,试图通过jQuery的$.get()创建一个简单的调用API并处理收到的数据。

问题在于 - 显然 - 这个函数被调用......好吧,无论何时。但是,我不希望它被调用(即它在代码中的位置)。

我会没事的
  1. get(...)内做所有事情,只要我可以使用来自父范围的循环,计数器等(就像我习惯的那样)
  2. 首先从get()电话中获取收到的数据然后再处理
  3. 但这似乎都不可能。

    我认为发生的事情就是人们在谈论异步JavaScript时的意思,如 AJ AX。很好,很好,但我如何解决我的问题?

    $(document).ready(function() {
      for (var i = 0; i < 5; i++) {
        console.log(i);
        $.get("test.php", function(data) {
          console.log(i);
        });
        console.log(i);
      }
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    给出

    00 11 22 33 44 44444

    但我希望它是

    000 111 222 333 444

    我希望这是有道理的。

    奖金问题:我是否会更好地使用PHP获取here所述的数据,按照here所述将其转换为JS并按计划继续?

    编辑/解决方案:

    我的奖金问题导致我最终采用这样的方式(简化):

    <script>
    <?php
    $data = array();
    
    for ($row = 0; $row < 5; $row++) {
        $response = json_decode(file_get_contents("test.php?access_token=".$row));
        array_push($data,$response);
    }
    
    $js_data = json_encode($data);
    echo "var data_all = ". $js_data .";\n";
    ?>
    
    $(document).ready(function(){
        //do JS stuff with the data_all array
    });
    </script>
    

    这样做的好处是不会让所有人都可以看到访问令牌。

    如果我的方法有问题,我很乐意在评论中阅读,否则我会在我找到一个有效的解决方案时考虑这个问题。感谢您指出这个问题的副本,这是一个有趣的阅读。

1 个答案:

答案 0 :(得分:0)

欢迎使用异步编程。

你将无法强制它让你循环你想要的。你必须通过异步的规则来玩,你不能反过来强迫它。

从基础层面来说,您必须习惯以异步方式运行异步代码。这就是为什么它有一个回调让你知道它已经完成。

如果你想连续处理多个异步请求,那么你想要做的就是以某种方式排队,然后在第一次完成时从队列中读出下一个异步请求。

// just a dummy async function that waits 100ms before finishing
const asyncFunction = (value) => new Promise(resolve => setTimeout(() => resolve(value), 100));

// data to call
const queue = ['A', 'B', 'C', 'D', 'E'];

const processQueue = (queue) => {
  if (queue.length == 0) {
    return Promise.resolve();
  } else {
    console.log('running', queue[0]);
    return asyncFunction(queue.shift())
      .then(val => {
        console.log(val);
        return processQueue(queue)
      });
  }
}

processQueue(queue)
  .then(() => console.log('all done'));

基本上,你有一些数据的队列(在我的例子中,是字母,但在你的情况下,可能是URL)。你拿第一个,然后关闭,等待它完成,然后运行队列中的下一个。然后重复此操作,直到它们全部完成。

上面的语法使用Promises(适用于$.get()和朋友),这通常是更现代的方法,但回调版本(如您的示例中)非常相似:

// just a dummy async function that waits 100ms before finishing
const asyncFunction = (value, callback) => setTimeout(() => callback(value), 100);

// data to call
const queue = ['A', 'B', 'C', 'D', 'E'];

const processQueue = (queue, callback) => {
  if (queue.length == 0) {
    callback();
  } else {
    console.log('running', queue[0]);
    asyncFunction(queue.shift(), val => {
      console.log(val);
      processQueue(queue, callback)
    });
  }
}

processQueue(queue, () => console.log('all done'));