【问题标题】:nodejs async/await nested API progressnodejs async/await 嵌套 API 进度
【发布时间】:2018-06-04 20:29:18
【问题描述】:

我有一个 API 可以搜索用户提供的术语,返回一组结果,然后为每个结果触发异步请求,并为第二批请求中的每一个获取结果。我希望 API 在发生时报告进度,而不仅仅是最终结果。所以,如果我执行以下请求,我应该得到这样的更新

$ curl 'http://server/?q=foobar'
searching for ${q}…
found 76… now getting images…
found 30 images… done
{
    result
}

大部分相关代码如下所示。 Fwiw,我正在为我的应用程序使用hapijs

let imagesOfRecords = {};

const getImages = async function (q) {

    console.log(`searching for ${q}…`);
    const uri = `http://remoteserver/?q=${q}`;
    const {res, payload} =  await Wreck.get(uri);
    const result = JSON.parse(payload.toString()).hits;
    const numOfFoundRecords = result.total;

    if (result.total) {

        console.log(`found ${result.total}… now getting images…`);
        const foundRecords = result.hits.map(getBuckets);
        Promise.all(foundRecords).then(function() {

            console.log(`found ${Object.keys(imagesOfRecords).length} images… done`);
            reply(imagesOfRecords).headers = res.headers;
        }).catch(error => { 
            console.log(error)
        });
    }
    else {
        console.log('nothing found');
        reply(0).headers = res.headers;
    }
};

const getBuckets = async function(record) {

    const { res, payload } = await Wreck.get(record.links.self);
    const bucket = JSON.parse(payload.toString()).links.bucket;
    await getImageFiles(bucket, record.links.self);
};

const getImageFiles = async function(uri, record) {

    const { res, payload } = await Wreck.get(uri);
    const contents = JSON.parse(payload.toString()).contents;
    imagesOfRecords[record] = contents.map(function(el) {
        return el.links.self; 
    });
};

一旦我可以实现这个,我的下一个任务就是在使用上述 API 的网络应用中实现这个渐进式更新。

【问题讨论】:

    标签: node.js promise async-await hapijs


    【解决方案1】:

    要显示后端请求的每个步骤的结果,您可以使用EventEmitter,它将在每个进度步骤上发出事件。您可以阅读有关事件here
    简单实现:

    const events = require('events');
    const eventEmitter = new events.EventEmitter();
    
    //your request code
    Promise.all(foundRecords).then(function() {
      console.log(`found ${Object.keys(imagesOfRecords).length} images… done`);
      eventEmitter.emit('progress');
      reply(imagesOfRecords).headers = res.headers;
    })
    
    const eventReaction = (e) => {
      // do something with event, console log for example.
    }
    eventEmitter.on('progress', eventReaction);
    

    您可以找到更多示例 herehere
    要向客户显示事件,您可以使用库socket.io。我认为您可以在documentation 中找到关于 socket.io 工作原理的非常简单的解释。
    如果你想在服务器或进程之间发送事件并且想更进一步,你可以阅读更多关于 0MQ(零 mq)和它的节点 implementation

    【讨论】:

    • 这太好了,谢谢。我会尝试这些建议。虽然,现在有些事情告诉我,这可能比值得更麻烦,因为我还必须为我的 API 的使用者提供一些区分进度更新和结果的方法。有很多尝试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 2020-03-09
    • 2018-07-05
    • 2015-11-10
    • 1970-01-01
    • 2018-05-27
    相关资源
    最近更新 更多