最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

nodejs asyncawait嵌套的API进度

IT培训 admin 16浏览 0评论

nodejs async / await嵌套的API进度

我有一个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的Web应用程序中实现此渐进式更新。

回答如下:

要在后端请求的每个步骤中显示结果,您可以使用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);

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

nodejs async / await嵌套的API进度

我有一个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的Web应用程序中实现此渐进式更新。

回答如下:

要在后端请求的每个步骤中显示结果,您可以使用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);

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

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论