仅在每个项目完成其方法调用后才返回

Posted

技术标签:

【中文标题】仅在每个项目完成其方法调用后才返回【英文标题】:Return only after each item has finished its method calls 【发布时间】:2022-01-24 01:16:24 【问题描述】:

一段时间以来,我一直在为这个项目中 javascript 的异步特性而苦苦挣扎。

关于这个主题有很多类似的问题,但我觉得它们都略有不同,让我很难找到可行的解决方案。

我一直在尝试使用这些方法创建一个 api。

getAll - 读取异步文件 审核 审核全部

我开始用回调来编写我的所有方法,虽然它很简单,但还可以。但现在它给我带来了问题。所以我用 util.promisify 写了一些包装器,效果很好。

我有这种完美的审计方法。

const audit = (req, res, next) => 
    Domains.audit(req.params.url)
        .then((data) =>  
            res.json(data);
        )
        .catch((err) => 
            res.json(err);
        )
;

它返回这个计划分配给“消息”的对象


    "warnings": [
        "This url 301 redirects to https://www.google.com. Please update your entry."
    ],
    "errors": []

问题出在这里。

我正在努力实现 auditAll 方法。 我尝试过使用回调和承诺,但它总是在我的审计调用修改我返回的“报告”之前返回

这是一些我一直未能创建的伪代码

auditAll(callback) 
    // Get all domains with getAll() and make them look like this
    report = 
        '123' : 
            'url' : 'https://google.com',
            'other_props' : '...'
        
        '124' : 
            'url' : 'https://google2.com',
            'other_props' : '...'
        
    ;

    // For each report item
        // run an audit which returns a message object
        // assign that to it's spot in the report
        report[item_key][messages] = audit(item.url)
    
    // Report returns to the browser before the audits finish with every solution I've implemented. 
    // They send to my console like 50ms later.
    callback(report)

【问题讨论】:

您提供的audit 函数似乎没有返回任何内容。除非你指的是Domains.audit,在这种情况下你没有提供代码。 您需要将每个报告返回给浏览器(一个一个响应?还是一次全部响应? 我要他们全部回来。 【参考方案1】:

您的 audit() 函数需要实际返回它正在创建的 Promise...

const audit = (req, res, next) => 
    return Domains.audit(req.params.url)
        .then((data) =>  
            res.json(data);
        )
        .catch((err) => 
            res.json(err);
        )
;

... 然后您的 auditAll() 方法需要等待所有 audit() 调用完成。由于看起来您正在为报告数组中的每个项目调用一次 audit(),因此使用 Array.map() 和 Promise.all() 可能看起来像这样:

Promise.all(
    Object.values(report).map(
        item => audit(item.url).then(
            message => item[messages] = message
        )
    )
).then(() => callback(report));

附录:实际上,您的问题有些不清楚 - auditAll 调用“audit(url)”,但您提供了“audit(req, res, next)”的代码,所以我不确定这些是如何相关的。这里的想法是 audit() 应该返回消息的承诺

audit(url)  return someAsyncFunc(url).then(() => message); 

然后可以按照我的描述使用。

【讨论】:

以上是关于仅在每个项目完成其方法调用后才返回的主要内容,如果未能解决你的问题,请参考以下文章

ADO.net 是仅在指定的存储过程调用之后返回结果,还是等到所有触发器都执行后才返回结果?

JQuery:如何仅在完成调整大小后才调用 RESIZE 事件?

十异步

循环函数中的异步调用。仅在异步完成时返回

仅在 spock 中模拟基于调用次数的方法返回

URLSession 下载任务委托仅在所有任务完成后调用