【问题标题】:Javascript array only running function that returns a promise on one element of arrayJavascript 数组仅运行函数,该函数在数组的一个元素上返回一个承诺
【发布时间】:2018-07-21 05:31:23
【问题描述】:

我已经发布了其他问题,但我觉得我应该简化一些事情

我有一个函数可以设置上下文并调用第二个函数在上下文中绘制线条。

我有这个:

var arr = [];

填充如下:

arr = [context,pre];

pre 看起来像pre = [[{x:n,y:m}],[{x:j,y:k}]];

所以,基本上,我有一个数组pre,其中包含坐标数组。该数组与上下文一起被推送到arr

arr 被返回并推入最终数组,比如final_arr,现在应该是这样的:final_arr = [[context1,pre1],[context2,pre2],...]

我的目标是遍历final_arr 并在不同的上下文中画线,由数组中的context 确定。例如,第一次迭代将访问final_arr[0] 并包含context1,pre1。这两个值被发送到一个函数wrap(context, pre),它返回一个promise。在这个wrap 函数中,调用了另一个函数animate(pre[i])。此函数获取pre 中的每个元素,它对应于一个坐标数组,并实际使用动画帧绘制线条。 animate() 也返回一个承诺。

目前,只绘制了一条路径,这似乎是因为只使用了final_arr 的一个值,即使我正在迭代它

我的迭代尝试:

final_arr.reduce((a,c) => a.then(() => wrap(c[0],c[1])), Promise.resolve());

var temp = Promise.resolve();
var i = 0;
for (i = 0; i < arr.length; i++){
    //window.alert(arr[i].length)
    var ct = arr[i][0];
    var line = arr[i][1];
    temp.then(() => wrap(ct,line));
}

下面是被调用的函数:

/*
*   Animation function draws a line between every point
*/              
var animate = function(p){
    return new Promise(function(resolve) {
        t = 1;
        var runAnimation = function(){
            if(t<p.length){
                context.beginPath();
                context.moveTo(p[t-1].x,p[t-1].y);
                context.lineTo(p[t].x,p[t].y);
                context.stroke();
                t++;
                requestAnimationFrame(function(){runAnimation()});
            } else {
                resolve()
            }
        };
        runAnimation();
    });
}
function wrap(ctx, lines){
    return new Promise(function(resolve) {
        var counter = 0;
        t = 1;
        var getAnimation = function(){
            if(counter < lines.length){
                context = ctx;
                lines.reduce((a, c) => a.then(() => animate(c)), Promise.resolve());
                counter++;
            } else {
                resolve()
            }
        };
        getAnimation();
    });
}

wrap中设置的context变量是js文件的全局变量

我希望以这种方式提出的问题能够明确我遇到的问题

感谢您的帮助

编辑:

尝试fiddle

编辑2:

奇怪的是,这行得通

if(final_arr.length == 1){
                    wrap(final_arr[0][0], final_arr[0][1]);
                } else if (final_arr.length == 2){
                    wrap(final_arr[0][0], final_arr[0][1]).then(wrap(final_arr[1][0], final_arr[1][1]));
                } else if (final_arr.length == 3){
                    wrap(final_arr[0][0], final_arr[0][1]).then(wrap(final_arr[1][0], final_arr[1][1])).then(wrap(final_arr[2][0], final_arr[2][1]));
                }

但是在使用这个的时候,线是同时画出来的(没关系,但不是首选)

【问题讨论】:

  • 一件快速的事情:你没有在函数内部声明t,所以它是一个在所有上下文中使用的全局变量。这会导致您的问题吗?
  • 一个小提琴玩会很好,但我认为你可以用 warp promise 函数填充 final_arr 并使用 Promise.All
  • @ScottSauyet 我不这么认为,因为对于一个人来说,每次调用 wrap 时它都会重置为 1(我相信?),当调用返回 arr 变量的函数时它会重置为 1 (不包括在内,因为它似乎在我的上一篇文章中引起了混淆)。这个想法是在动画中将其重置为 1,因此 pre 中的每个元素都从头开始,并在 wrap 中设置为 1,因此 animate 的最后一次迭代的任何剩余部分都是固定的
  • @mr.void 我正在做一个小提琴,由于某种原因它不想运行任何东西......我刚接触 JS 4 天,所以它很有趣。我查看了promise.all,但很困惑它是如何工作的,必须先调用一个函数来做某事......介意一个我可以尝试的例子吗?
  • 我确实认为 Fiddle 会有所帮助。我还是不明白t。看起来每个动画都会干扰其他动画。我也不明白getAnimation。顺便说一句,对于学习该语言 4 天的人来说,这是相当复杂的代码!

标签: javascript arrays animation promise


【解决方案1】:

edit:刚刚在wrapif 语句中发现了缺少的resolve => 返回的Promise 将永远不会被解决...

我建议在进行任何微优化之前先使用更简单的 wrap 版本:

function wrap(ctx, lines){
  return new Promise(function(resolve) {
    lines.forEach(p => animate(p, ctx));
    resolve();
  });
}

在完成所有微任务后(即在所有 Promise 之后)调用对 requestAnimationFrame 的回调 - 请参阅 When will requestAnimationFrame be executed?

所以全局变量 context 的值对于所有回调将是相同的,即多次绘制同一条线或竞争条件或其他取决于 context 内部的东西

我会摆脱全局变量,只使用函数参数和局部变量:

var animate = function(p, ctx) {
  var t ...
  ... ctx.beginPath()

【讨论】:

  • 不幸的是,实施后没有任何变化。我需要更改变量名称以远离全局还是 JS 创建一个具有相同名称但新范围的新变量?
  • 嗯,局部变量的意义在于它们不必是全局唯一的,所以是的,你可以在不同的地方使用相同的名称...
  • 我认为它在其他语言中是一样的,但问起来也无妨
  • wrap 函数使用if(){}else{},而else 包含resolve(),当counter 大于lines.length 时不会被调用?
  • 提示:不要使用lines.forEach(...)。应该使用 return lines.reduce(...) 形式的单行代码。
猜你喜欢
  • 2017-05-30
  • 1970-01-01
  • 2021-03-11
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-13
相关资源
最近更新 更多