返回承诺的Javascript顺序函数

返回承诺的Javascript顺序函数,javascript,arrays,animation,promise,Javascript,Arrays,Animation,Promise,我需要按顺序运行函数,以便按正确的顺序设置动画,但我遇到了一些问题。代码基本上检查一些条件并将值存储在数组中(未显示)。这些值作为参数传递给某些需要按顺序运行的函数。我用承诺来实现这一点 此代码将所需函数(及其参数)存储在数组func\u call var func_call = []; for (var i = 0; i < s_list.length; i++){ //lower if (!isUpper) { canvas = document.get

我需要按顺序运行函数,以便按正确的顺序设置动画,但我遇到了一些问题。代码基本上检查一些条件并将值存储在数组中(未显示)。这些值作为参数传递给某些需要按顺序运行的函数。我用承诺来实现这一点

此代码将所需函数(及其参数)存储在数组
func\u call

var func_call = [];
for (var i = 0; i < s_list.length; i++){
    //lower
    if (!isUpper) {
        canvas = document.getElementById("myCanvas");
        context = canvas.getContext("2d");
    //upper
    } else {
        canvas = document.getElementById("myCanvasUpr");
        context = canvas.getContext("2d");
    }
    func_call.push(function () {get_path(context, s_list[i], d_list[i], final_arr);});
    func_call.push(function () {draw_marker(context, s_list[i], d_list[i], isFirst[i], isLast[i]);});
}
func_call.push(function() {wrap(final_arr)});
func_call.reduce((cur, next) => cur.then(next()), Promise.resolve());
wrap
在这里

function draw_marker(context, source, desti, isFirst, isLast) {
return new Promise(function(resolve) {
    /*
     * Get the point number of the point on the path that the source and destination connect to
     */

    var start = string_to_point[source];
    var finish = string_to_point[desti];

    /*
     *   Marker 
     */
    if (isFirst) {
        var marker1 = new Image();
        marker1.onload = function(){
            marker1._x = point_coord[start[0]][0]-1;
            marker1._y = point_coord[start[0]][1]-44;
            context.drawImage(marker1, marker1._x, marker1._y,marker1.width,marker1.height);
        };
        marker1.src = "images/map_pin.png";
    } else {
        context.fillStyle = 'green';
        context.beginPath();
        context.arc(point_coord[start[0]][0], point_coord[start[0]][1], 8, 0, 2 * Math.PI);

        context.strokeStyle = "green";
        context.stroke();
        context.fill();
    }
    if (isLast) {
        /*var marker2 = new Image();
        marker2.onload = function(){
            marker2._x = point_coord[finish[0]][0]-15;
            marker2._y = point_coord[finish[0]][1]-22;
            context.drawImage(marker2, marker2._x, marker2._y,marker2.width,marker2.height);
        };
        marker2.src = "images/x_marks.png";*/
    } else {
        context.fillStyle = 'red';
        context.beginPath();
        context.arc(point_coord[finish[0]][0], point_coord[finish[0]][1], 6, 0, 2 * Math.PI);

        context.strokeStyle = "#ff0000";
        context.stroke();
        context.fill();
    }
    resolve();
});
}
function wrap(arr){
console.log("in wrap");
var getAnimation = function(context, lines){
    console.log("Get animation");
    console.log(lines);
    return new Promise(function(resolve) {
        context.beginPath();
        lines.reduce((a, c) => a.then(() => animate(context,c)), Promise.resolve());
        resolve();
    });
};  
arr.reduce((a,c) => a.then(() => getAnimation(c[0],c[1])),Promise.resolve());
}
var animate = function(context, p){
return new Promise(function(resolve) {
    console.log("in animate");
    var t = 1;
    context.lineCap = "round";
    context.lineWidth = 5;
    //context.strokeStyle = "#ff0000";
    context.strokeStyle = "#ff3c3c";
    //context.strokeStyle = "#f38f1d";
    var runAnimation = function(){
        if(t<p.length){
            console.log("running animation");
            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 {
            console.log("run animation resolved");
            resolve()
        }
    };
    runAnimation();
});
}
animate
在这里

function draw_marker(context, source, desti, isFirst, isLast) {
return new Promise(function(resolve) {
    /*
     * Get the point number of the point on the path that the source and destination connect to
     */

    var start = string_to_point[source];
    var finish = string_to_point[desti];

    /*
     *   Marker 
     */
    if (isFirst) {
        var marker1 = new Image();
        marker1.onload = function(){
            marker1._x = point_coord[start[0]][0]-1;
            marker1._y = point_coord[start[0]][1]-44;
            context.drawImage(marker1, marker1._x, marker1._y,marker1.width,marker1.height);
        };
        marker1.src = "images/map_pin.png";
    } else {
        context.fillStyle = 'green';
        context.beginPath();
        context.arc(point_coord[start[0]][0], point_coord[start[0]][1], 8, 0, 2 * Math.PI);

        context.strokeStyle = "green";
        context.stroke();
        context.fill();
    }
    if (isLast) {
        /*var marker2 = new Image();
        marker2.onload = function(){
            marker2._x = point_coord[finish[0]][0]-15;
            marker2._y = point_coord[finish[0]][1]-22;
            context.drawImage(marker2, marker2._x, marker2._y,marker2.width,marker2.height);
        };
        marker2.src = "images/x_marks.png";*/
    } else {
        context.fillStyle = 'red';
        context.beginPath();
        context.arc(point_coord[finish[0]][0], point_coord[finish[0]][1], 6, 0, 2 * Math.PI);

        context.strokeStyle = "#ff0000";
        context.stroke();
        context.fill();
    }
    resolve();
});
}
function wrap(arr){
console.log("in wrap");
var getAnimation = function(context, lines){
    console.log("Get animation");
    console.log(lines);
    return new Promise(function(resolve) {
        context.beginPath();
        lines.reduce((a, c) => a.then(() => animate(context,c)), Promise.resolve());
        resolve();
    });
};  
arr.reduce((a,c) => a.then(() => getAnimation(c[0],c[1])),Promise.resolve());
}
var animate = function(context, p){
return new Promise(function(resolve) {
    console.log("in animate");
    var t = 1;
    context.lineCap = "round";
    context.lineWidth = 5;
    //context.strokeStyle = "#ff0000";
    context.strokeStyle = "#ff3c3c";
    //context.strokeStyle = "#f38f1d";
    var runAnimation = function(){
        if(t<p.length){
            console.log("running animation");
            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 {
            console.log("run animation resolved");
            resolve()
        }
    };
    runAnimation();
});
}
var animate=function(上下文,p){
返回新承诺(函数(解析){
console.log(“在动画中”);
var t=1;
context.lineCap=“round”;
context.lineWidth=5;
//context.strokeStyle=“#ff0000”;
context.strokeStyle=“#ff3c”;
//context.strokeStyle=“#f38f1d”;
var runAnimation=function(){
if(t如果目标JavaScript环境支持,您可以使用它。如果不支持,您可以实现一个类似Babel的编译器并以这种方式使用它


如果你不想走这条路,有一个Bluebird,一个承诺库,允许你用
{concurrency:1}
选项调用。这将按顺序调用承诺。

我不完全理解这一点。你到底想做什么?创建一个“无限”
然后
链,这样每个函数在另一个函数启动之前完成?那么问题是什么?您只需继续调用
然后
就可以解决问题。例如,假设
s_list
有两个源。
d_list
和另一个“参数”数组也将有2个元素。使用这些元素,我希望运行
get\u path
,然后
draw\u markers
,然后
get\u path
然后
draw\u marker
然后
wrap
。对
get\u path
draw\u markers
的每个调用都需要有不同的参数,例如s\u list[0]对于一个调用,为下一个
somePromise调用s_list[1]。然后(()=>{/*在这里选择参数*/get_path(s_list[0]);})。然后(()=>{/*…*/});
如果参数没有以奇怪的方式选择(在这种情况下,您可能必须手动选择),您可以通过循环或其他机制将其自动化。@不管怎样……我如何将其放入循环中?我认为
reduce
将完成类似的事情
func\u call.reduce((cur,next)=>cur.then(next()),Promise.resolve());
您正在调用
next
函数,而不是将其传递给then。删除括号,代码(可能)会使用标准的promise库没有办法做到这一点吗?async/await的工作方式有什么不同,我是新手javascript@ChrisM查看演示以了解async/await,它基本上是一种以同步方式调用承诺的方法。我强烈建议您查看它。完全错过了链接,现在查看它。它看起来像是如果我理解正确的话,异步函数是一个异步运行的函数,wait基本上会停止在该函数中的执行,直到用wait调用的函数的承诺返回?在我的示例中,我是否只需要创建一个异步函数并使用一个循环来等待我需要的每个函数调用?例如
while(){await get_path();await draw_marker;}
?没错!非常方便。