Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Can';无法从异步函数中获取'count'_Javascript_Asynchronous_D3.js - Fatal编程技术网

Javascript Can';无法从异步函数中获取'count'

Javascript Can';无法从异步函数中获取'count',javascript,asynchronous,d3.js,Javascript,Asynchronous,D3.js,我有下面的代码,d3.json是一个异步函数。当我的计数等于100时,我尝试在循环中运行它。我的while循环在第一次迭代后停止,因为count发生在异步函数中,所以我没有像应该的那样多次运行它。如何获得正确的计数,使我的while循环在保持异步特性的同时继续执行 $(document).ready(function() { $('button').click(function() { var start = new Date().getTime();

我有下面的代码,
d3.json
是一个异步函数。当我的
计数等于100时,我尝试在循环中运行它。我的
while
循环在第一次迭代后停止,因为
count
发生在异步函数中,所以我没有像应该的那样多次运行它。如何获得正确的计数,使我的
while
循环在保持异步特性的同时继续执行

    $(document).ready(function() {
    $('button').click(function() {
        var start = new Date().getTime();
        while(count == 100){
            console.log("first iteration");
            count = 0;
            d3.json("/api/messages/" + offset, function(error, json) {
                if (error) return console.warn(error);
                data = json;
                for(var i = 0; i < data.messages.length; i++){
                    console.log(data.messages[i].date);
                    count++;
                    console.log(count);
                }
            });
            offset += 100;
        }
            var end = new Date().getTime();
            var time = end - start;
            console.log("Time to execute : " + time);
    });
});
$(文档).ready(函数(){
$(“按钮”)。单击(函数(){
var start=new Date().getTime();
而(计数=100){
log(“第一次迭代”);
计数=0;
d3.json(“/api/messages/”+偏移量,函数(错误,json){
如果(错误)返回控制台。警告(错误);
data=json;
对于(var i=0;i
编辑:我正在尝试将我的呼叫设置为如下所示。每次调用时,您都会检查并确保返回了100个项目(计数),如果没有,则停止while循环

  • /api/messages/0
  • /api/messages/100
  • /api/messages/200
  • /api/messages/300
  • /api/messages/400
  • /api/messages/500
  • /api/messages/600

  • 我们的想法是链接这个
    ajax
    调用,直到到达某个截止点(在本例中,偏移量大于max)

    对于这个答案,我将调用
    d3.json
    更改为
    jQuery.getJSON
    ,因为它更容易在JSFIDLE上调试,但概念完全相同。我还必须更改请求的url以使用JSFIDLE调试api

    var start = new Date().getTime();
    var offset = 0;
    var maxOffset = 600;
    var baseUrl = "/echo/json"; // change this to /api/messages in production
    
    var callback = function(json) {
        console.log(json);
    
        console.log("current offset: " + offset);
    
        data = json;
        //  ... do something with data ...
    
        // increment the offset
        offset += 100;
    
        // don't run any more and return the execution time
        if (offset > maxOffset) {
            var end = new Date().getTime();
            var time = end - start;
            console.log("Time to execute : " + time);
            return; // don't run any more
        }
    
        // offset too small so run another getJSON call with our callback
        $.getJSON(baseUrl + "?" + offset, callback);
    }
    
    // when button is click, start the json call chain
    $('button').click(function() {            
        // change the "?" to "/" in production
        $.getJSON(baseUrl + "?" + offset, callback);
    });
    
    如果您需要帮助将此转化为您的确切问题,请告诉我


    是JSFIDLE。

    以下是我的做法:

    创建一个接受相关参数的函数:
    start
    offset、
    increment
    ,最重要的是一个
    done
    回调,该回调应该在最后执行

    此函数包含一个辅助函数,它将调用API、检查结果并调用自身或
    done
    回调:

    function fetchAllMessages(start, increment, done) {
        var messages = [];
        (function nextCall(offset) {
            d3.json("/api/messages/" + offset, function (error, data) {
                if (error) return done(error, messages);
                if (!data.messages) return done("unexpected response format", messages);
    
                messages.push.apply(messages, data.messages);
                if (data.messages.length === increment) {
                    nextCall(offset + increment);
                } else {
                    done(null, messages);
                }
            });
        })(start);
    }
    
    现在,您可以通过单击事件处理程序简单地使用它:

    $(function() {
        $('button').click(function() {
            var start = Date.now();
    
            fetchAllMessages(0, 100, function (err, messages) {
                var end = Date.now();
                if (err) console.warn(err);
                console.log(messages);
                console.log("Time to execute : " + (start - end));
            });
        });
    });
    

    您正在尝试运行
    '/api/messages/1'
    '/api/messages/2'
    <代码>'/api/messages/100'
    ?是,但以100为增量。因此,我从一个api中提取数据,该api一次只允许提取100个元素,并允许在每个请求时进行偏移。因此,在每次迭代中,我都会将偏移量增加100。你能在你的问题中显示一个预期url调用的列表吗?@Victory我已经开始添加,当我在我的应用程序中包含这样的代码,然后进行调试时,当我单击按钮时,它只是跳过
    fetchAllMessages
    函数。我尝试了你的方法,并使用
    $document.ready()
    而不是在JSFIDLE和我的应用程序中使用
    $(functoin(){…
    ,当我按下按钮时,什么都没有发生。我在我的应用程序中设置了一些调试器(在
    $.getJSON(baseUrl+“?”+偏移量,回调)之前设置了
    控制台.log(“按下按钮”)
    )
    在按钮单击中,但也没有打印出来。我用
    $(文档)包装了按钮单击功能。准备好了
    ,它工作了。