【问题标题】:javascript / typescript await doesn't work inside loop [duplicate]javascript / typescript await 在循环内不起作用[重复]
【发布时间】:2021-12-31 04:49:36
【问题描述】:

我有以下带有嵌套异步函数的类,但是,不知何故

await Jimp.loadFont(font)

不会阻止循环执行,而是下面的源代码给出了输出

2
3
index 0 start
index 0 about to loadFont xxxxxx
index 0 start
index 0 about to loadFont xxxxx
/* crash due to this unintended async behavior */

我希望它等到 Jimp 加载字体,即理想的输出是

2
3
index 0 start
index 0 about to loadFont xxxxxx
index 0 loadFont start
index 0 loadFont end
index 0 loadFont end
index 1 start
index 1 about to loadFont xxxxxx
index 1 loadFont start
index 1 loadFont end
index 1 loadFont end
index 2 start
index 2 about to loadFont xxxxxx
index 2 loadFont start
index 2 loadFont end
index 2 loadFont end
/* repeat for 1 more time as inputGif.frames.length = 2 */

这里是源码

export class GifWriter {
    async writeTextOnGif(options: GifWriterOptions) {
        let src = this.getSrc(options.src);
        let dest = options.dest;
    
        var frames: GifFrame[] = [];
    
        await GifUtil.read(src).then(async inputGif => {

            console.log(inputGif.frames.length);
            console.log(options.text_options.length);

            inputGif.frames.forEach(async frame => {
                var jimpCopied = GifUtil.copyAsJimp(Jimp, frame);

                for (var index = 0; index < options.text_options.length; index++) {

                    console.log(`index ${index} start`);

                    let text = options.text_options[index].text;
                    let font = this.getFont(options.text_options[index].font_path, options.text_options[index].font_color, options.text_options[index].font_size);
                    let alignmentX = this.getAlignmentX(options.text_options[index].alignmentX);
                    let alignmentY = this.getAlignmentY(options.text_options[index].alignmentY);
                    let positionX = options.text_options[index].positionX;
                    let positionY = options.text_options[index].positionY;
                    // print(font, x axis offset, y axis offset, text options, maxWidth, maxHeight)
                    let [offsetX, offsetY, maxWidth, maxHeight] = this.getPosition(jimpCopied, positionX, positionY);

                    console.log(`index ${index} about to loadFont ${font}`);

                    await Jimp.loadFont(font).then(font => {
                        console.log(`index ${index} loadFont start`);
                        jimpCopied.print(font, offsetX, offsetY, {
                            text: text,
                            alignmentX: alignmentX,
                            alignmentY: alignmentY
                            },
                            maxWidth,
                            maxHeight);
                        console.log(`index ${index} end`);
                    });
                    console.log(`index ${index} end`);
                }
                console.log(`create GifFrame`);
                const GifCopied = new GifFrame(jimpCopied.bitmap,{
                    disposalMethod: frame.disposalMethod,
                    delayCentisecs: frame.delayCentisecs,
                });
                GifUtil.quantizeSorokin(GifCopied, 256);
                frames.push(GifCopied); 
            });
        });
        // write to the destination file.
        GifUtil.write(dest, frames);
    }

我的猜测是 inputGif.frames.forEach(async frame => { 正在使每个帧异步执行?但是如果我删除 async 关键字,那么我不能将 await 与 Jimp.loadFont 一起使用,有人可以给个建议我怎样才能达到预期的输出?

【问题讨论】:

  • 请减少到最小的可重现示例
  • 使用循环代替forEach 方法

标签: javascript typescript async-await


【解决方案1】:

Async/Await 与 for 循环一起使用,它与 forEach 循环不符合预期。因此,我对代码进行了一些编辑,并使用 for 循环代替了 forEach。这是更新的代码,请尝试这种方法一次

async writeTextOnGif(options: GifWriterOptions) {
  let src = this.getSrc(options.src);
  let dest = options.dest;

  var frames: GifFrame[] = [];

  let inputGif = await GifUtil.read(src);

  console.log(inputGif.frames.length);
  console.log(options.text_options.length);

  for (let parentLoopIndex = 0, len = inputGif.frames.length; parentLoopIndex < len; parentLoopIndex++) {
    let frame = inputGif.frames[parentLoopIndex];
    var jimpCopied = GifUtil.copyAsJimp(Jimp, frame);
    let promise; 
    for (var childLoopIndex = 0; childLoopIndex < options.text_options.length; childLoopIndex++) {

        console.log(`index ${childLoopIndex} start`);
        /* To keep it short, i've removed some code in the asnwer. */
        let newFont = await Jimp.loadFont(font);
        console.log(`index ${childLoopIndex} loadFont start`);
        jimpCopied.print(newFont, offsetX, offsetY, {
            text: text,
            alignmentX: alignmentX,
            alignmentY: alignmentY
            },
            maxWidth,
            maxHeight);
        console.log(`index ${childLoopIndex} end`);
    }
    console.log(`create GifFrame`);
    const GifCopied = new GifFrame(jimpCopied.bitmap,{
        disposalMethod: frame.disposalMethod,
        delayCentisecs: frame.delayCentisecs,
    });
    GifUtil.quantizeSorokin(GifCopied, 256);
    frames.push(GifCopied); 
  }

  // write to the destination file.
  GifUtil.write(dest, frames);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多