我正在尝试为上述问题编写代码。我试着寻找解决方案。这就是我现在所拥有的。
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var drawColorLine = function(start, end, color) {
var deltaX, deltaY, i = 0,
currLength = 0,
isHor, isVert;
deltaX = end[0] - start[0];
deltaY = end[1] - start[1];
context.strokeStyle = color;
isHor = deltaX === 0 ? 0 : 1;
isVert = deltaY === 0 ? 0 : 1;
function draw() {
context.beginPath();
context.moveTo(start[0] + currLength * isHor, start[1] + currLength * isVert);
currLength = currLength + 0.5 * i;
context.lineTo(start[0] + currLength * isHor, start[1] + currLength * isVert);
context.stroke();
if (currLength <= Math.max(deltaX, deltaY)) {
i = i + 1;
requestAnimationFrame(draw);
}
}
draw();
};
drawColorLine([40, 40], [100, 40], '#116699');
drawColorLine([40, 40], [40, 100], '#bb11dd');
&#13;
<canvas id='canvas' width='400' height='400'></canvas>
&#13;
问题是两者同时被绘制出来。一个人应该追随另一个人。使用promsises是否可以在第一个函数执行时延迟第二个函数,然后执行第二个函数?我试着读一下Promises,但我无法将我理解的内容翻译成代码。
提前致谢。
答案 0 :(得分:5)
是的,您可以使用promises,尽管出于学习目的,您可能希望首先编写纯回调解决方案。
您需要查看我的rules of thumb承诺开发。我们在这里应用它们:
每个异步函数都必须返回一个promise。
在您的案例中,这些将是drawColorLine
,draw
和requestAnimationFrame
。
由于requestAnimationFrame
是一个原生的,原始异步的函数,遗憾的是它仍然需要回调,我们必须promisify它:
function getAnimationFrame() {
return new Promise(function(resolve) {
requestAnimationFrame(resolve); // this promise never gets rejected
// TODO: cancellation support :-)
});
}
异步操作后的所有内容都会进入.then()
回调:
function drawColorLine(start, end, color) {
… // initialisation
function draw() {
… // do work
// always return a promise:
if (/* furter work */) {
i++;
return getAnimationFrame().then(draw); // magic happens here :-)
} else {
return Promise.resolve(…); // maybe have a path object as eventual result?
// or anything else, including nothing (no arg)
}
}
return draw(); // returns a promise - but don't forget the `return`
}
瞧!
drawColorLine([40, 40], [100, 40], '#116699').then(function() {
return drawColorLine([40, 40], [40, 100], '#bb11dd');
}).then(console.log.bind(console, "both lines drawn"));
答案 1 :(得分:2)
尝试使用.animate(),jQuery.Deferred()
<?php
require_once '../../inc/config.php';
$response = array();
$response['errors'] = false;
$id = $_REQUEST['id'];
if(!empty($_FILES)){
//set default data arrays
$names = array(); //stores file names
$files = array(); //stores the file data
$mime_types = array(); //store the file type as a mime type
//force each file name to the names array
foreach($_FILES['file']['name'] as $name){
array_push($names, $name);
}
//force the file data into its own array spot in the files array
foreach($_FILES['file']['tmp_name'] as $temp){
array_push($files, prepareImageDBString($temp));
}
//force the mimetypes into the mime_types array
foreach($_FILES['file']['type'] as $type){
array_push($mime_types, $type);
}
//process all three of the file arrays simultaneously so that no data is left out
for($i = 0; $i < count($names); $i++){
$file_name = $names[$i];
$file_data = $files[$i];
$mime_type = $mime_types[$i];
//set the query for the data to go into the note_file table in the database
$q = "INSERT INTO brb.files (customer__id, file_name, file_data, mime_type)
VALUES('$id', '$file_name', '$file_data', '$mime_type')";
//run the query
if($stmt = $CONN->prepare($q)){
//process any errors that may occur
if(!$stmt->execute()){
printf("Error Message: %s\n", $CONN->error);
}
}
}
}
echo json_encode($response);
function prepareImageDBString($filepath){
$out = 'null';
$handle = fopen($filepath, 'r');
if($handle){
$content = fread($handle, filesize($filepath));
$content = bin2hex($content);
fclose($handle);
$out = $content;
}
return $out;
}
?>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var drawColorLine = function(start, end, color) {
// create new `deferred` object
var dfd = new $.Deferred(),
deltaX, deltaY, i = 0,
currLength = 0,
isHor, isVert,
// create animation object
props = $({"prop":i});
deltaX = end[0] - start[0];
deltaY = end[1] - start[1];
context.strokeStyle = color;
isHor = deltaX === 0 ? 0 : 1;
isVert = deltaY === 0 ? 0 : 1;
function draw(n) {
context.beginPath();
context.moveTo(start[0] + currLength * isHor
, start[1] + currLength * isVert);
currLength = currLength + 0.5 * n;
context.lineTo(start[0] + currLength * isHor
, start[1] + currLength * isVert);
context.stroke();
if (currLength <= Math.max(deltaX, deltaY)) {
// create object to animate,
// do animation stuff
props.animate({"prop":1}, {
// set duration of animation
duration:10,
complete:function() {
// increment `n`:`i`
n = n + 1;
// call `draw` with `n` as parameter
draw(n)
}
})
} else {
// if `currLength > Math.max(deltaX, deltaY)`,
// resolve `deferred` object,
// set `canvas` element as `this` at `.then()`
// pass `deltaX`, `deltaY`, `currLength`, `n``
// arguments to `.then()`
dfd.resolveWith(canvas, [deltaX, deltaY, currLength, n]);
}
}
draw(i);
// return jQuery promise object
return dfd.promise()
};
// draw first line
drawColorLine([40, 40], [100, 40], '#116699')
.then(function() {
console.log("first line complete", arguments, this);
// draw sencond line
return drawColorLine([40, 40], [40, 100], '#bb11dd');
}).then(function() {
console.log("second line complete", arguments, this);
})