如何将循环和 async/await 与 Gulp 一起使用?

How do I use loops and async/await with Gulp?

我正在使用 11ty 构建一个网站,并使用 Gulp,我正在尝试 下载 来自 URL 的一些图像存储在数组中然后 然后在下载完成后对它们做其他事情

我对 async/await 和 Promises 的理解非常基础,我无法按照我想要的顺序使用它。

这是我的 Gulp 任务:

const {dest, gulp} = require("gulp");
const download = require("gulp-download");

arr = [
    // Some images' URLs
]

const promises = () => {

    function first(){

        for(let i = 0; i < arr.length; i++){
            download(arr[i])
            .pipe(dest("src/images/promises/"));
            console.log(i);
        }

    }

    async function second() {
        await first();
        console.log('--- ON TO THE NEXT TASK ---');
        // Code for the next task would go here
    }

    second();

}

module.exports = promises;

想法是 first() 中的循环进入 brrrr,然后当它完成时,second() 中的代码被执行。实际上,这是我在终端中看到的:

[11:12:45] Using gulpfile ~/[...]/gulpfile.js
[11:12:45] Starting 'promises'...
0
1
2
--- ON TO THE NEXT TASK ---
[gulp] Downloading https://[...]/image1.jpg...[gulp] Downloading https://[...]/image2.jpg...[gulp] Downloading https://[...]/image3.jpg... 0.3076966000480284% 0.05975911747906604% 0.05752515731185281% Done
 0.26226932127136454% 0.2759738467431939% Done
 Done
[11:12:49] The following tasks did not complete: promises
[11:12:49] Did you forget to signal async completion?

看起来我的 second() 函数在下载完成之前执行了。然后是我不确定如何处理的“信号异步完成”,以及它是否必须对主要问题做些什么。

正如我在评论中所说,first 不是 return 承诺,也不是异步函数,因此 await first() 实际上并不等待任何东西。

现在,我实际上并不知道 download([i]) 具体做什么,但是如果它 return 是一个承诺,你可以这样做:

function first(){
        const promises = [];
        for(let i = 0; i < arr.length; i++){
            const promise = download(arr[i])
                               .pipe(dest("src/images/promises/"));
            promises.push(promise);
        }
        return Promise.all(promises);
    }

这样,first() 执行 return 承诺,await first() 等待 Promise.all 完成。

如果 download().pipe() 没有 return 某种承诺,那么......你将不得不想办法让它做到......


编辑

看起来有一个库可以将 gulp-download 变成一个承诺,所以你可能想使用它:

https://www.npmjs.com/package/gulp-stream-to-promise

这可能是这样的:

function first(){
        const promises = [];
        for(let i = 0; i < arr.length; i++){
            const stream = download(arr[i])
                               .pipe(dest("src/images/promises/"));
            const promise = gulpStreamToPromise(stream);
            promises.push(promise);
        }
        return Promise.all(promises);
    }