Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript用于循环,等待函数回调_Javascript_Jquery_Asynchronous - Fatal编程技术网

Javascript用于循环,等待函数回调

Javascript用于循环,等待函数回调,javascript,jquery,asynchronous,Javascript,Jquery,Asynchronous,我有一个for循环,它调用自身内部的函数。该函数有一个回调,但是for循环不会等待它完成并继续工作 for循环实际上完成得如此之快,以至于下一个操作(服务于应该在for循环中填充的文档)在第一个函数调用完成之前完成 下面是我实际使用的调用的内容,其中images是一个数组,包含指向图像的外部URL: // New jsPDF Document var doc = new jsPDF(); doc.setFontSize(12); // For each image we add the im

我有一个for循环,它调用自身内部的函数。该函数有一个回调,但是for循环不会等待它完成并继续工作

for循环实际上完成得如此之快,以至于下一个操作(服务于应该在for循环中填充的文档)在第一个函数调用完成之前完成

下面是我实际使用的调用的内容,其中images是一个数组,包含指向图像的外部URL:

// New jsPDF Document
var doc = new jsPDF();

doc.setFontSize(12);

// For each image we add the image to the document as an image
for (var index = 0; index < images.length; index++) {

    // We only add pages after the first one
    if (index !== 0) {
        doc.addPage();
    }

    // This puts the URL of the active element at the top of the document
    doc.text(35, 25, images[index].path);

    // Call to our function, this is the 'skipped' portion
    convertImgToDataURLviaCanvas(images[index].path, function(base64Img) {
        console.log('An image was processed');
        doc.addImage(base64Img, 15, 40, 180, 180);
    });
}

doc.save('demo.pdf');
console.log('Document served!');
在前面的示例中,甚至行
doc.text(35,25,images[index].path)
正确地将URL写入页面顶部。因为它包含在数组中,并沿着迭代器工作。然而,for循环在第一个图像添加到文档之前就已经完成了

使用
console.log
您将看到:
'Document served!'
在第一个
“处理图像”之前
。我们的目标是将其颠倒过来,在提供
文档之前,每一个
图像都会被处理。
被输出出现


如何实现此功能?

要保证图像的顺序,使用承诺很简单

var promises = images.map(function(image, index) {
    return new Promise(function(resolve) {
        convertImgToDataURLviaCanvas(image.path, function(base64Img) {
            resolve(base64Img);
        });
    });
}
Promise.all(promises).then(function(results) {
    results.forEach(function(base64Img, index) {
        if (index !== 0) {
            doc.addPage();
        }
        doc.text(35, 25, images[index].path);
        console.log('An image was processed');
        doc.addImage(base64Img, 15, 40, 180, 180);
    });
    doc.save('demo.pdf');
    console.log('Document served!');
});
对于完整性(尽管未选中)-保证图像顺序并将addPage/文本放在正确位置的非承诺方式

var base64 = new Array(images.length); // base64 images held here
images.forEach(function(image, index) {
    // Call to our function, this is the 'skipped' portion
    convertImgToDataURLviaCanvas(image.path, function(base64Img) {
        console.log('An image was processed');
        // We only add pages after the first one
        base64[index] = base64Img;
        done++;
        if (done == images.length) {
            base64.forEach(function(img64, indx) {
                if (indx !== 0) {
                    doc.addPage();
                }
                // This puts the URL of the active element at the top of the document
                doc.text(35, 25, images[indx].path);
                doc.addImage(img64, 15, 40, 180, 180);
            }
            doc.save('demo.pdf');
            console.log('Document served!');
        }
    });
}
一种方法如下

var done = 0; // added this to keep counf of finished images
for (var index = 0; index < images.length; index++) {

    // We only add pages after the first one
    if (index !== 0) {
        doc.addPage();
    }

    // This puts the URL of the active element at the top of the document
    doc.text(35, 25, images[index].path);

    // Call to our function, this is the 'skipped' portion
    convertImgToDataURLviaCanvas(images[index].path, function(base64Img) {
        console.log('An image was processed');
        doc.addImage(base64Img, 15, 40, 180, 180);
        // added this code, checks number of finished images and finalises the doc when done == images.length
        done++;
        if (done == images.length) {
            // move the doc.save here
            doc.save('demo.pdf');
            console.log('Document served!');
        }
        // end of new code
    });
}

保证图像的顺序,使用承诺很简单

var promises = images.map(function(image, index) {
    return new Promise(function(resolve) {
        convertImgToDataURLviaCanvas(image.path, function(base64Img) {
            resolve(base64Img);
        });
    });
}
Promise.all(promises).then(function(results) {
    results.forEach(function(base64Img, index) {
        if (index !== 0) {
            doc.addPage();
        }
        doc.text(35, 25, images[index].path);
        console.log('An image was processed');
        doc.addImage(base64Img, 15, 40, 180, 180);
    });
    doc.save('demo.pdf');
    console.log('Document served!');
});
对于完整性(尽管未选中)-保证图像顺序并将addPage/文本放在正确位置的非承诺方式

var base64 = new Array(images.length); // base64 images held here
images.forEach(function(image, index) {
    // Call to our function, this is the 'skipped' portion
    convertImgToDataURLviaCanvas(image.path, function(base64Img) {
        console.log('An image was processed');
        // We only add pages after the first one
        base64[index] = base64Img;
        done++;
        if (done == images.length) {
            base64.forEach(function(img64, indx) {
                if (indx !== 0) {
                    doc.addPage();
                }
                // This puts the URL of the active element at the top of the document
                doc.text(35, 25, images[indx].path);
                doc.addImage(img64, 15, 40, 180, 180);
            }
            doc.save('demo.pdf');
            console.log('Document served!');
        }
    });
}
一种方法如下

var done = 0; // added this to keep counf of finished images
for (var index = 0; index < images.length; index++) {

    // We only add pages after the first one
    if (index !== 0) {
        doc.addPage();
    }

    // This puts the URL of the active element at the top of the document
    doc.text(35, 25, images[index].path);

    // Call to our function, this is the 'skipped' portion
    convertImgToDataURLviaCanvas(images[index].path, function(base64Img) {
        console.log('An image was processed');
        doc.addImage(base64Img, 15, 40, 180, 180);
        // added this code, checks number of finished images and finalises the doc when done == images.length
        done++;
        if (done == images.length) {
            // move the doc.save here
            doc.save('demo.pdf');
            console.log('Document served!');
        }
        // end of new code
    });
}


预期结果将等待
doc.addPage()
要在调用
convertimgtodautaurliviacanvas
之前完成,请执行其回调
doc.addPage();预期结果是确保按顺序调用
convertimgtodautaurliviacanvas
doc.save()
部分放入for循环下的
convertimgtodautaurliviacanvas
的回调中?
doc.addPage()
convertimgtodautaurliviacanvas
的回调<首先调用code>convertimgtodautauralviacanvas
,然后调用
doc.addPage()
?“使用console.log,您将看到第一个‘处理了图像’之前的‘已送达文档’”
console.log(‘已送达文档’)是synchronous@guest271314是的,具体地说,
doc.addPage()
位于回调内部<代码>convertimgtodautaurlviacanvas(图像[索引]。路径,函数(base64Img){'这是回调'})@alix,这将尝试保存文件的次数。我认为最后一次回调实际上是正确的文件,但我认为这种方式不会导致正确的解决方案
要在调用
convertimgtodautaurliviacanvas
之前完成,请执行其回调
doc.addPage();预期结果是确保按顺序调用
convertimgtodautaurliviacanvas
doc.save()
部分放入for循环下的
convertimgtodautaurliviacanvas
的回调中?
doc.addPage()
convertimgtodautaurliviacanvas
的回调<首先调用code>convertimgtodautauralviacanvas
,然后调用
doc.addPage()
?“使用console.log,您将看到第一个‘处理了图像’之前的‘已送达文档’”
console.log(‘已送达文档’)是synchronous@guest271314是的,具体地说,
doc.addPage()
位于回调内部<代码>convertimgtodautaurlviacanvas(图像[索引]。路径,函数(base64Img){'这是回调'})@alix,这将尝试保存文件的次数。我想最后一次回调实际上是正确的文件,但我不认为这样就可以找到正确的解决方案。太好了!给我一点时间来测试一下。问题是关于
doc.save
调用得太早-任何对where
doc.addPage
逻辑的重写都应该是无关的,超出了问题的范围。就我而言,Dayeah,我还在@JaromandaX检查它,addPage和doc.text确实需要添加到回调中,否则首先会添加所有页面。如果您愿意使用承诺,以正确的顺序添加图像非常容易-请参见编辑answer@Erick-我添加了一个非承诺保证订单答案-我可以编辑答案,只包括最后两个版本,这两个版本应解决所有问题,即使是问题中最初未提及的问题!给我一点时间来测试一下。问题是关于
doc.save
调用得太早-任何对where
doc.addPage
逻辑的重写都应该是无关的,超出了问题的范围。就我而言,Dayeah,我还在@JaromandaX检查它,addPage和doc.text确实需要添加到回调中,否则首先会添加所有页面。如果您愿意使用承诺,以正确的顺序添加图像非常容易-请参见编辑answer@Erick-我添加了一个非承诺保证订单答案-我可以编辑答案,只包括最后两个版本,这两个版本应解决所有问题,即使是问题中最初未提及的问题