javascript - 为什么 node.js 承诺即使放在 then() 块中也不会解决?
问题描述
我想获得以下工作流程:
- 获取一些图片的 URL
- 将这些 URL 传递给另一个方法以下载它们,并返回下载的路径
- 使用这些路径获取图像并使用pdfkit创建 PDF 文件
经过大量修改后,我的代码如下所示 -
nightmare
.goto(url)
.wait('body')
.evaluate( ()=>document.querySelector('body').innerHTML)
.end()
.then((response) => {
return getJSONData(response);
})
.then((data) => {
return processJSONData(data);
})
.then((pages) => {
return createFile(pages);
})
.catch(err => {
console.log(err);
});
getJSONData(data)
使用cheerio解析HTML,并processJSONData(data)
使用image-downloader下载图像。根据我的理解,由于这是一个承诺链,这意味着每个 then() 内部的执行将是异步的,但 then() 块本身将按顺序执行。在运行代码时,我看到即使前两个 then() 块是按顺序执行的(到目前为止),该createFile(pages)
块也会立即执行,从而创建一个损坏的 PDF 文件。这可能是什么原因?如何确保then()
块同步执行,即每个块then()
仅在前一个 then 解决后运行?
完整的代码可以在这里找到。
解决方案
您不必等待所有异步操作在 内完成processJSONData()
,而只是等待其中的某些部分。考虑更改如下:
function processJSONData(data){
// map() instead of forEach() to get a promise per request
const reqs = data.map(element => {
// return the inner promise chain to be collected
return download.image(element)
.then( ({filename}) => {
console.log("Saved to ",filename);
return filename;
});
});
// return a promise that waits for all of them to be finished
return Promise.all( reqs );
}
推荐阅读
- javascript - Youtube Iframe Api 无法在实时网站上运行
- django - 过滤每个查询集中类别中的 X 个最新条目
- c++ - 链接下载包时出现大量 LD 链接错误
- python - 是否有更快、更有效的方式来处理我的数据?
- asp.net-core - ASP.NET Core 3.1 的 Microsoft Graph 片段示例 - 身份验证错误
- azure-devops - Azure Devops Server 2019 是否包含“环境”功能
- python - 如何检查 Youtube 视频 URL 在 Python 中是否有效?
- html - 我怎样才能使输入的宽度在左边更小?
- python - 如何在 yaml 文件中为处理程序指定用户定义的对象以记录 python
- javascript - 正则表达式匹配javascript中的所有字符