返回promises的Javascript顺序函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了返回promises的Javascript顺序函数相关的知识,希望对你有一定的参考价值。
我需要按顺序运行函数才能以正确的顺序动画,但我遇到了一些问题。代码基本上检查一些条件并将值存储在数组中(未显示)。这些值作为参数传递给某些函数,这些函数需要按顺序运行。我正在使用承诺来实现这一目标
此代码将所需的函数(及其参数)存储在数组func_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());
get_path就在这里
function get_path(context, source, desti, arr){
return new Promise(function(resolve) {
var starting_points = string_to_point[source];
var ending_points = string_to_point[desti];
console.log("get path");
console.log(starting_points);
/*
* Define the variables
* i -> iterator count
* seg_1 -> points of starting exhibit and closest point on the path
* seg_2 -> points of ending exhibit and closest point on path
* main_path -> the points along the main path
* reverse_flag -> denotes whether the direction is forward or reverse
*/
var i;
var seg_1 = [];
var seg_2 = [];
var main_path = [];
var secondary_path = [];
var reverse_flag = false;
var secondary_flag = false;
var primary_flag = false;
var starting_point = starting_points[0];
var ending_point = ending_points[0];
var vertices = [];
var pre = [];
var secondary_vertices = [];
var points = [];
var secondary_points = [];
/*
* Add the first two segments
*/
if(starting_points.length == 3){
for(var j = starting_points[0]; j <= starting_points[1]; j++){
seg_1.push({x:point_coord[j][0] , y:point_coord[j][1]});
}
starting_point = starting_points[2];
}
if(ending_points.length == 3){
for(var j = ending_points[0]; j <= ending_points[1]; j++){
seg_2.push({x:point_coord[j][0] , y:point_coord[j][1]});
}
ending_point = ending_points[2];
}
if(starting_point == 260 && ending_point == 260){
ending_point = -1;
} else if (starting_point == 260){
for(var j = 260; j <= 267; j++){
seg_1.push({x:point_coord[j][0] , y:point_coord[j][1]});
}
starting_point = 72;
} else if (ending_point == 260){
for(var j = 260; j <= 267; j++){
seg_2.push({x:point_coord[j][0] , y:point_coord[j][1]});
}
ending_point = 72;
}
/*
* Handles reverse direction. Switches starting and end points and sets the reverse_flag
*/
if (ending_point != -1 && starting_point > ending_point){
temp = starting_point;
starting_point = ending_point;
ending_point = temp;
reverse_flag = true;
}
/*
* Add points to main_path
*/
for (i = starting_point; i <= ending_point; i++){
var b = point_coord[i];
/*if(i >= 122){
secondary_flag = true;
secondary_path.push({x:b[0],y:b[1]});
} else {
primary_flag = true;
main_path.push({x:b[0],y:b[1]});
}*/
primary_flag = true;
main_path.push({x:b[0] , y:b[1]});
}
/*
* Creates the full path -> combination of seg_1, seg_2, and main_path
*/
if(reverse_flag){
if(primary_flag){
if(secondary_flag){
vertices = seg_1.concat(secondary_path.reverse());
secondary_vertices = main_path.reverse().concat(seg_2);
context.beginPath()
context.arc(pathways[121][0], pathways[121][1], 8, 0, 2 * Math.PI);
context.fillStyle = 'green';
context.fill();
context.beginPath();
context.arc(pathways[122][0], pathways[122][1], 6, 0, 2 * Math.PI);
context.fillStyle = 'red';
context.fill();
} else {
vertices = seg_1.concat(main_path.reverse(),seg_2.reverse());
}
} else {
if(secondary_flag){
vertices = seg_1.concat(secondary_path.reverse(),seg_2);
} else {
}
}
} else {
if(primary_flag){
if(secondary_flag){
vertices = seg_1.concat(main_path);
secondary_vertices = secondary_path.concat(seg_2);
context.beginPath();
context.arc(pathways[122][0], pathways[122][1], 8, 0, 2 * Math.PI);
context.fillStyle = 'green';
context.fill();
context.beginPath()
context.arc(pathways[121][0], pathways[121][1], 6, 0, 2 * Math.PI);
context.fillStyle = 'red';
context.fill();
} else {
vertices = seg_1.concat(main_path,seg_2.reverse());
}
} else {
if(secondary_flag){
vertices = seg_1.concat(secondary_path,seg_2);
} else {
vertices = seg_1.concat(seg_2);
}
}
}
/*
* Calculate the extra points for animation, and draw the animation
*/
if(secondary_vertices.length == 0){
points = calcWaypoints(vertices);
pre.push(points);
} else {
points = calcWaypoints(vertices);
secondary_points = calcWaypoints(secondary_vertices);
pre.push(points, secondary_points);
}
arr.push([context,pre]);
console.log(arr);
resolve();
});
}
draw_marker
在这里
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();
});
}
wrap
在这里
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());
}
animate
在这里
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();
});
}
目标是根据需要运行get_path
和draw_markers
的许多组合,然后运行wrap
,后者又调用animate
。每个animate
都需要在下一个开始之前完成
我该如何做到这一点?
谢谢。如果需要更多细节,请告诉我
答案
如果目标javascript环境支持,您可以使用async/await。如果没有,你可以实现像Babel这样的编译器并以这种方式使用它。
如果您不想走那条路,那么Bluebird是一个Promise库,允许您使用Promise.map
选项调用{ concurrency: 1 }
。这将按顺序调用promise。
以上是关于返回promises的Javascript顺序函数的主要内容,如果未能解决你的问题,请参考以下文章