循环承诺!如何? [英] Promise in a loop! How to?

查看:146
本文介绍了循环承诺!如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使这段代码工作一段时间,但我似乎无法理解.这是一个实时更新的图形,它的每个点都包含一个[x,y]数组,因此是一个数组数组.

输入是来自服务器的JSON列表,该列表将更新同一JSON对象(因此它将更改一个JSON并且仅更新值):

[
  {
    "Value": 10,
    "Name": "Name of variable"
  }
]

我只需要提取值.

我这样尝试过:

var getValueData = async function() {
    var valueJSON = await Promise.resolve($.getJSON( "{% url 'get_value' %}" ));
    return valueJSON[0]['Value'];
};

var data = [];
var totalPoints = 100;
var updateInterval = 1000;
var now = new Date().getTime();

function getData() {
    data.shift();

    while (data.length < totalPoints) {
        var value = [now += updateInterval,
                    getValueData().then(function(result) {
                        result;
                    })
                   ];

        data.push(value);
    };
};

基本上,getData()试图从JSON构建一个X = timestamp.now()和Y = "Value"的数组,然后将该数组推入我的"overall"数据数组.

以此方式将value做成[<timestamp>, Unresolved]的数组.

这样做:

while (data.length < totalPoints) {
    getZScoreData().then(function (result) {
        var valueArray = [now += updateInterval, result];
        data.push(valueArray);
    });
};

如果我console.log(value),则使valueArray成为实际的[<timestamp>, <JSON "value"],除了这种方式似乎会永久挂起服务器并为制表符消耗大量RAM,就好像我在进行无限循环(数百次)一样.向Web服务器获取请求的数量,即使最大长度应为100).我不确定Promise内将如何发生这种行为.

这是在示例中可用的代码:

while (data.length < totalPoints) {     
    var y = Math.random() * 100;
    var value = [now += updateInterval, y];

    data.push(value);
};

这似乎很简单.在var value = [now += updateInterval, y];中说y的地方,使"y"从我的API中获取值.

我不知道如何实现这一目标.

我正在遵循此Flot示例中的示例,但我只是无法使其与AJAX或Promise的实际实时值一起工作(我什至尝试获取).

实时更新表"的所有示例最终都只使用math.random(),这很容易引起误解,因为它只是在移动,但并不是真正的实时.

我认为我没有正确解决循环中的承诺,但是由于经验不足,目前我什至不知道哪里出了问题.

我不确定在代码中我应该去哪里Y = "live value",或者我是否必须在某个地方返回结果?我对Promises或AJAX不太熟悉.

解决方案

在循环中执行承诺很少是一个好主意,您通常希望使用Promise.all()一次执行多个Promises,并将其结果收集到一个循环中.数组:

function getData() {
    // Note: Why is this here?
    data.shift();

    var promises = [];
    while (data.length < totalPoints) {
        promises.push(getValueData());
    }

    Promise.all(promises).then(results => {
        for (let result of results) {
            var value = [
                now += updateInterval,
                result
            ];
            data.push(value);
        }
    });
};

MDN在Promises上有一些很好的材料: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises

附带说明,即使使用Promise.all(),同时执行100个AJAX请求听起来也很费劲.如果对后端有任何影响,则应该尝试优化后端,或者调查Worker以批量执行请求.

I've been trying to get this bit of code to work for a while, and I just can't seem to get it. It's for a live-updating graph, that takes in an array of [x, y] for each point, so an array of arrays.

The input is a JSON list coming from a server, that updates that same JSON object (so it changes one JSON and updates only the value):

[
  {
    "Value": 10,
    "Name": "Name of variable"
  }
]

I need to extract the value only.

I tried it like this:

var getValueData = async function() {
    var valueJSON = await Promise.resolve($.getJSON( "{% url 'get_value' %}" ));
    return valueJSON[0]['Value'];
};

var data = [];
var totalPoints = 100;
var updateInterval = 1000;
var now = new Date().getTime();

function getData() {
    data.shift();

    while (data.length < totalPoints) {
        var value = [now += updateInterval,
                    getValueData().then(function(result) {
                        result;
                    })
                   ];

        data.push(value);
    };
};

Basically, getData() is trying to build an array of X = timestamp.now(), and Y = "Value" from JSON, then push that array into my "overall" data array.

Doing it this way makes value an array of [<timestamp>, Unresolved].

Doing it this way:

while (data.length < totalPoints) {
    getZScoreData().then(function (result) {
        var valueArray = [now += updateInterval, result];
        data.push(valueArray);
    });
};

Makes valueArray be an actual [<timestamp>, <JSON "value"], if I console.log(value), except this way seems to hang the server forever and consume a huge amount of RAM for the tab, as if I was doing an infinite loop (hundreds of get requests to the web server, even though the max length should 100). I'm not sure of the what's going inside the Promise to get this behavior though.

This here is the code that works in the example:

while (data.length < totalPoints) {     
    var y = Math.random() * 100;
    var value = [now += updateInterval, y];

    data.push(value);
};

It seems straightforward enough. Where it says y (in var value = [now += updateInterval, y];) make "y" get the value from my API.

I have no clue how to actually achieve this.

I'm following the example from this Flot example but I just can't manage to make it work with an actual live value from AJAX or Promise (I even tried fetch).

All examples for "live updating table" end up just using math.random(), which is pretty misleading, as it just kinda moves about, but isn't really live.

I believe I'm not resolving the promise in the loop properly, but due to lack of experience, at this point I'm not even sure what is wrong.

I'm not sure where in my code I would go Y = "live value", or whether I have to return result somewhere? I'm not familiar with Promises or AJAX that much.

解决方案

Promises in loops are rarely a good idea, you'll usually want to use Promise.all() to execute multiple Promises at once, and get their results collected in an array:

function getData() {
    // Note: Why is this here?
    data.shift();

    var promises = [];
    while (data.length < totalPoints) {
        promises.push(getValueData());
    }

    Promise.all(promises).then(results => {
        for (let result of results) {
            var value = [
                now += updateInterval,
                result
            ];
            data.push(value);
        }
    });
};

MDN has some good materials on Promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises

As a side note, executing 100 AJAX requests at the same time sounds pretty strenuous, even with Promise.all(). You should either try to optimize the backend if you have any influence over it, or look into Workers to execute the requests in batches.

这篇关于循环承诺!如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆