2017-05-24 12 views
0

mdns-js 패키지를 사용하여 다음과 같은 검색 코드가 있습니다.
에 ./lib/deviceDiscovery.js이 추천NodeJS : Promise.all에 의해 반환 된 약속은 개별 약속이 있지만 해결되지 않았습니다

var mdns = require('mdns-js'); 
const browsers = new Map(); 
const INFINITE = -1; 

function createABrowser(theServiceType, timeout) { 
    if (browsers.has(theServiceType)) { 
     return; 
    } 

    return new Promise(function(resolve, reject) { 
     var browser = mdns.createBrowser(theServiceType); 
     browser.on('ready', function() { 
      browsers.set(theServiceType, browser); 
      resolve(browser); 
     }); 

     if (timeout != INFINITE) { 
      setTimeout(function onTimeout() { 
       try { 
        browser.stop(); 
        browsers.delete(browser.serviceType); 
       } finally { 
        reject('browser ' + browser.toString() + ' timed out.'); 
       } 
      }, timeout); 
     } 
    }); 
} 

module.exports.startService = function(services, timeout) { 
    timeout = timeout || INFINITE; 
    promises = []; 
    services.forEach(function(service) { 
     promises.push(createABrowser(service, timeout)); 
    }); 
    return Promise.all(promises); 
} 

module.exports.stopService = function() { 
    browsers.values().forEach(function(browser) { 
     browser.stop(); 
    }); 
    browsers.clear(); 
} 

module.exports.getDevices = function() { 
    if (browsers.size == 0) { 
     reject('service was stopped'); 
    } else { 
     const promises = []; 
     for (let browser of browsers.values()) { 
      promises.push(new Promise(function(resolve, reject) { 
       try { 
        browser.discover(); 
        browser.on('update', function(data) { 
         mfps = new Set(); 
         const theAddresses = data.addresses; 
         theAddresses.forEach(function(element) { 
          mfps.add(element); 
         }); 
         resolve(mfps); 
        }); 
       } catch(err) { 
        reject(err); 
       } 
      })); 
     }; 
     return Promise.all(promises).then(function(values) { 
      return new Set(values); 
     }, function(reason) { 
      return reason; 
     }); 
    } 
} 

다른 파일을 사용

const DeviceDiscoveryService = require('./lib/deviceDiscovery'); 
var co = require('co'); 

co(function *service() { 
    yield DeviceDiscoveryService.startService([internetPrinter, pdlPrinter, unixPrinter], TIMEOUT); 
    yield DeviceDiscoveryService.getDevices(); 
}).catch(onerror); 

function onerror(err) { 
    // log any uncaught errors 
} 

문제는 제 수율이 중단이고; getDevices 함수에 의해 반환 된 약속은 무기한 해결되지 않는 것으로 보입니다. 개별 약속이 해결 된 것을 볼 수 있습니다.

startService은 유사한 Promise.all (...)을 사용하지만 잘 작동합니다.

또 다른 관련 질문은 mdns-js에 관한 것입니다. 각 (입력) 서비스에 대해 브라우저가 여러 업데이트를받는 것으로 보입니다. 하지만 첫 번째 업데이트 이벤트 후 각 브라우저에 대한 약속을 해결합니다 ... 여러 업데이트 및 방법을 기다릴 필요가 있습니까?
힌트를 주시면 감사하겠습니다. 감사.

+0

나는'co()'를 사용하는 이점을 정말로 모르겠다. (DeviceDiscoveryService.getDevices) .then (console.log); ' – trincot

답변

1

업데이트를 공유하면 (서비스가 이미 존재하는 경우 undefined를 반환하는 대신) 모든 시간에 createABrowser에서 약속을 반환한다고 생각합니다. 약속을 되풀이하지 않고서는 Promise.all()이 해결되지 않을 것이라고 생각합니다.

대신 서비스가 이미 존재하는 경우 상단에 약속을 작성하고 해결 한 다음 그 약속을 반환하십시오.

getDevices() 호출의 경우 약속을 반환하지 않고 거부를 실행 중입니다. 이게 효과가 있니?

module.exports.getDevices = function() { 
    if (browsers.size == 0) { 
     // Create a new promise, return it, and immediately reject 
     return new Promise(function(resolve, reject) { reject('service was stopped') }; 
     // reject('service was stopped'); <- There wasn't a promise here 
    } else { 
     const promises = []; 
     for (let browser of browsers.values()) { 
      promises.push(new Promise(function(resolve, reject) { 
       try { 
        browser.discover(); 
        browser.on('update', function(data) { 
         mfps = new Set(); 
         const theAddresses = data.addresses; 
         theAddresses.forEach(function(element) { 
          mfps.add(element); 
         }); 
         resolve(mfps); 
        }); 
       } catch(err) { 
        reject(err); 
       } 
      })); 
     }; 
     return Promise.all(promises).then(function(values) { 
      return new Set(values); 
     }, function(reason) { 
      return reason; 
     }); 
    } 
} 
+0

서비스가 이미 존재할 때 케이스를 업데이트했습니다. 그러나 _startService_는 이미 작동하고있었습니다. 보류중인 약속은 _getDevices_에 대한 것으로 Promise를 맨 위로 되돌리려면 업데이트되었지만 반환 된 약속은 여전히 ​​걸려 있습니다 ... – sharpthor

+0

답변을 편집했습니다. 이거 정리 해 봤니? –