使用 P-Queue 节点模块对 Promise 进行排队

fun*_*dry 1 javascript node.js

我正在使用 node-fetch 向 Amazon 存储桶发出 HEAD 请求以检查文件的状态,但我正在尝试设置模块P-Queue以控制并发性。

我有一个数组,resources包含我的所有数据,包括要在该存储桶中检查的文件路径。然后像这样映射数组:

resources.map((resource) => {
    queue
        .add(validateImage(resource))
        .catch((err) => console.error(`Failed to add resource to queue: ${err}`));
});
Run Code Online (Sandbox Code Playgroud)

这就是我的validateImage函数的样子:

const validateImage = (resource) => {
    const path = `https://${bucketUrl}/${env}/${resource.path}`;
    verbose && console.log(`Fetching resource: ${path}`);
    return fetch(
        path,
        {
            method: 'HEAD',
            timeout
        }
    )
    .then(res => {
        validatedResources.push({
            ...resource,
            statusCode: res.status
        });
    })
    .catch(err => {
        validatedResources.push({
            ...resource,
            error: err.type
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

但是每当我运行这个脚本时,我都会收到错误 Failed to add resource to queue: TypeError: fn is not a function我有资源一样多。

我已经检查过从 validateImage 返回的是一个 Promise 并且我还尝试从 p-queue github 重写示例以使用 fetch (怀疑是原因):

const PQueue = require('p-queue');
const fetch = require('node-fetch');

const queue = new PQueue({concurrency: 1});

queue.add(() => fetch(
    'http://sindresorhus.com'),
    { method: 'HEAD'}
).then(() => {
    console.log('Done: sindresorhus.com');
});

queue.add(() => fetch('http://ava.li')).then(() => {
    console.log('Done: ava.li');
});
Run Code Online (Sandbox Code Playgroud)

这确实有效,所以我不确定在哪里看?

Luc*_* S. 5

queue.add 需要一个函数,但是您正在传递一个 Promise。

当您调用 时queue.add(validateImage(resource)),引擎首先评估validateImage(resource),它返回一个 Promise。然后它评估queue.add(<returned promise>).

只需将调用更改为箭头函数: queue.add(() => validateImage(resource))