如何在 node.js 中的特定持续时间后强制解决承诺? [复制]

Posted

技术标签:

【中文标题】如何在 node.js 中的特定持续时间后强制解决承诺? [复制]【英文标题】:How to force resolve a promise after certain duration in node.js? [duplicate] 【发布时间】:2021-04-04 09:07:54 【问题描述】:

我正在尝试从他们的 url 下载大量图像,然后在 Node.js 中创建一个 PDF 文件。我正在使用image-downloader 模块下载承诺链中的图像,然后在解决所有承诺后,使用另一个模块images-to-pdf 来触发pdf 的创建。 问题是大多数承诺会在大约 5-6 秒内立即解决,但是有一些图像需要相当长的时间来下载。我想在一定的等待间隔后强制触发 PDF 创建。可以吗? 这是代码

var promises = data.map(function(element)
    return download.image(element)
    .then( (filename) => 
        console.log("Saved to ",filename);
        return filename;
    )
);

Promise.all(promises).then(function (data)
    var fileName = url.slice(url.indexOf("files")+7, url.length-1).replace("/","_")+".pdf";
    data.forEach(
        (element) => console.log(element);
    );
    imagesToPdf(data, fileName)
    .then(console.log(" PDF creation done."));
)
.catch ((error) => 
    console.error(error);
);

data.map 中传递的数据是以下性质的 JSON 对象 -

[
   
    url:"https://path//to//image//001.jpg",
    dest:"local//path//to//image//001.jpg"
  ,
   
    url:"https://path//to//image//002.jpg",
    dest:"local//path//to//image//002.jpg"
  ,
   
    url:"https://path//to//image//003.jpg",
    dest:"local//path//to//image//003.jpg"
  ,
  ...
]

【问题讨论】:

请使用回调。然后您可以在下载图像时捕捉到这一刻。之后就可以使用imagetopdf.. @ArtemMedianyk - 向已经使用 Promise 的代码添加普通回调是没有意义的。 不要使用承诺。只需使用 data.map(element, i) => something @ArtemMedianyk -- download.image(element) 是异步的并返回一个承诺。您必须使用某些东西来进行异步错误处理并知道它们何时全部完成。这就是 Promise 的构建目的,这里的核心操作已经使用了 Promise。一直建议不要在一系列已经使用 Promise 的异步操作中使用 Promise 是没有意义的。 【参考方案1】:

您可以使用Promise.race() 为每个图像承诺添加超时,如果您要解决它,那么您需要使用一些标记值来解决它(我在此示例中使用null),您可以测试,以便您知道在处理结果时跳过它。

function timeout(t, element) 
    return new Promise(resolve => 
        // resolve this promise with null
        setTimeout(resolve, t, element);
    );


var promises = data.map(function(element) 
    const maxTimeToWait = 6000;
    return Promise.race([download.image(element).then(( filename ) => 
        console.log("Saved to ", filename);
        return filename;
    ), timeout(maxTimeToWait)]);
);

然后,在处理来自Promise.all() 的结果的代码中,您需要检查null 并跳过那些,因为那些是超时的。

【讨论】:

在此之前我有没有办法用与特定图像相关联的任何内容来解决承诺? @srdg - 只需在 timeout() 函数中添加一个参数,该参数是您的常量,然后将其传递给您在超时函数中看到的null。那将使用该值解决承诺。 好的,我知道我需要传递这个参数。如何访问内容?我可以timeout(maxTimeToWait, element)吗? 只有一次超时更有效 承诺并与它竞争所有下载。 @Roamer-1888 是的,但是图像的性质使得每个图像都需要不同的时间来解决。我担心他们可能无法在一场共同的比赛中得到解决。只是出于好奇,我如何使比赛变得普遍?可以请教吗?

以上是关于如何在 node.js 中的特定持续时间后强制解决承诺? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 Node.js 中的“请求过多”错误?

如何从 Cloud Firestore 数据库中获取 node.js 中的特定字段值?

node js中的异步编程通过mongoose模型传递常量/预定义的强制值

如何使用 node.js 和 Promises 将特定行的行添加到文件的内容

如何以编程方式仅从 node.js 中的数据库(MySQL)中导出特定表? [关闭]

如何使用 Node.js 查询 mysql 数据库以通过 url 中的名称获取特定用户(字段),而不仅仅是通过 ID