2017-12-22 31 views
0

사용자가 제공 한 용어를 검색하고 결과 배열을 반환 한 다음 각 결과에 대한 비동기 요청을 실행하고 각 요청의 두 번째 일괄 처리에 대한 결과를 얻는 API가 있습니다. . API가 최종 결과가 아닌 진행 상황을보고하기를 바랍니다. 그래서, 다음과 같은 요청을하면, 내가 그렇게 업데이 트를 받아야한다nodejs async/중첩 된 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를 사용하는 웹 응용 프로그램에서이 진보적 인 업데이 트를 구현하는 것입니다.

답변

1

백엔드 요청의 각 단계에서 결과를 표시하려면 EventEmitter을 사용하면 각 진행 단계에서 이벤트가 방출됩니다. here 이벤트에 대해 읽을 수 있습니다.
간단한 구현 : 당신이 herehere 찾을 수 있습니다

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); 

더 많은 예제.
클라이언트에 이벤트를 표시하려면 라이브러리 socket.io을 사용할 수 있습니다. socket.io가 어떻게 작동하는지에 대한 간단한 설명을 documentation에서 찾을 수 있다고 생각합니다.
서버 나 프로세스간에 이벤트를 보내고 싶다면 조금 더 가고 싶다면 0MQ (제로 mq)에 대해 더 읽고 노드는 implementation

+0

입니다. 나는 그 제안을 시험해 볼 것이다. 지금은 무언가가 내 API의 소비자에게 진행 업데이트와 결과를 구분할 수있는 방법을 제공해야하기 때문에 가치있는 것보다 더 어려울 수도 있다고합니다. 실험 할 많은 것들. – punkish