【问题标题】: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,在这种情况下你没有提供代码。
  • 您需要将每个报告返回给浏览器(一个一个响应?还是一次全部响应?
  • 我要他们全部回来。

标签: javascript node.js promise callback


【解决方案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); }

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 2016-12-10
    • 2018-12-02
    相关资源
    最近更新 更多