2016-12-13 154 views
0

因此,我试图运行服务器测试功能,使用节点和请求。我的目标是运行一组服务器对象,构建一组成功的服务器ping,并返回具有最佳优先级的一个数组(硬编码到服务器对象中)。这里是我的代码到目前为止:解决之前forEach循环完成的承诺

//brings in http script availability 
var request = require('request'); 

//set of test servers 
var serverSet = [ 
     { 
     "url": "http://doesNotExist.askdex.co", 
     "priority": 1 
     }, 
     { 
     "url": "http://tricon.co", 
     "priority": 7 
     }, 
     { 
     "url": "http://offline.bing.co", 
     "priority": 2 
     }, 
     { 
     "url": "http://google.com", 
     "priority": 4 
     }, 
     { 
     "url": "http://yahoo.com", 
     "priority": 6 
     } 
]; 

//inform user of process taking place 
console.log("We are about to test some server requests for you, please stand by."); 


function serverTest(url, priority) { 
    //creates options to allow for request timeout 
    var options = { 
     url: url, 
     timeout: 5000 
    }; 
    return new Promise (
     function(resolve, reject) { 
      request(options, function(err, res, body) { 
       //if (err) {console.log("There was an error: " + err)}; 
       //test if server responds with a positive status 
       if (res !== undefined) { 
        if (res.statusCode >= 200 && res.statusCode <= 299) { 
         //console.log("response from online server is " + res.statusCode); 
         resolve({"url": url, "priority": priority}); 
        } else 
        if (res.statusCode >= 300 && res.statusCode <= 399) { 
         //console.log("response from redirected server is " + res.statusCode); 
         reject("The server is not working"); 
        } else 
        if (res.statusCode >= 400 && res.statusCode <= 499) { 
         //console.log("response from not working server is " + res.statusCode); 
         reject("The server is broken"); 
        }//==> end of inner if/else statement 
       } else { 
        reject("Server is unresponsive"); 
       }//==> end of outer if/else statement 
      });//==> end of get request 
     } 
    ); 
}; 

//call of function to run program 
//var test0 = serverTest(serverSet[0].url, serverSet[0].priority).then(function(resolve){console.log("resolution is: "+ JSON.stringify(resolve))}).catch(function(reject){console.log(reject)}); 
//console.log("Test0: "+ test0); 
//var test1 = serverTest(serverSet[1].url, serverSet[1].priority).then(function(resolve){console.log("resolution is: "+ JSON.stringify(resolve))}).catch(function(reject){console.log(reject)}); 
//console.log("Test1: "+ JSON.stringify(test1)); 
//var test2 = serverTest(serverSet[2].url, serverSet[2].priority).then(function(resolve){console.log("resolution is: "+ JSON.stringify(resolve))}).catch(function(reject){console.log(reject)}); 
//console.log("Test2: "+ JSON.stringify(test2)); 
//var test3 = serverTest(serverSet[3].url, serverSet[3].priority).then(function(resolve){console.log("resolution is: "+ JSON.stringify(resolve))}).catch(function(reject){console.log(reject)}); 
//console.log("Test3: "+ test3); 
//var test4 = serverTest(serverSet[4].url, serverSet[4].priority).then(function(resolve){console.log("resolution is: "+ JSON.stringify(resolve))}).catch(function(reject){console.log(reject)}); 
//console.log("Test4: "+ JSON.stringify(test4)); 

function findServer(array) { 
    var build = []; 
    return new Promise (
     function(resolution, rejection) { 
      array.forEach(function(server){ 
       serverTest(server.url, server.priority) 
        .then(function(resolve){ 
         if (typeof resolve === "object") { 
          console.log("findServer resolve = " + JSON.stringify(resolve)); 
          build.push(resolve); 
          console.log("build = " + JSON.stringify(build)); 
          return build; 
         } 
        }) 
        .catch(function(error){ 
         //console.log("Error: " + error); 
        }); 
      }); 
        resolution(build); 
      // if (onlineServers.length == 0) { 
      // //console.log("No online servers."); 
      // reject('Error: No servers are online.'); 
      // }//==> end of if statement 
     } 
    ) 
}; 

findServer(serverSet).then(function(result) { 
    console.log("The result is " + JSON.stringify(result)); 
    }).catch(function(error){ 
     console.log("The error is " + error); 
    }); 
// function findServer(array) { 
// return new Promise (
//  function(resolution, rejection) { 
//   var build = []; 
//   array.forEach(function(server){ 
//    serverTest(server.url, server.priority).then(function(resolve){ 
//      if (typeof resolve === "object") { 
//       console.log("findServer resolve = " + JSON.stringify(resolve)); 
//       build.push(resolve); 
//       console.log("build = " + JSON.stringify(build)); 
//       resolution(build); 
//      } 
//     }).catch(function(error){ 
//      //console.log("Error: " + error); 
//     }); 
//   }); 
//   // if (onlineServers.length == 0) { 
//   // //console.log("No online servers."); 
//   // reject('Error: No servers are online.'); 
//   // }//==> end of if statement 
//  } 
// ) 
// }; 




// findServer(serverSet).then(function(result){ 
    //  console.log(result); 
    //  console.log(onlineServers); 
    //  //condition check and modification if more than one server response is successful 
    //  if (result.length > 1) { 
    //   result.sort(function(a,b){ 
    //    return a.priority - b.priority; 
    //   }) 
    //   console.log(result[0].url + " has the lowest available priority."); 
    //  } else { 
    //   console.log(result[0].url + " has the lowest available priority."); 
    //  }//==> end of if statement 
    // }).catch(function(error){ 
    //  console.log(error); 
    // }); 

注释代码包含大量的尝试来测试和找出其他方法来使这项工作。

+0

可能的重复[如何返回来自异步调用的响应?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-调用) –

+0

'let findServers =(servers)=> Promise.all(servers.map(s => serverTest(s.url,s.priority))' – royhowie

+0

@royhowie我有这个作为我的答案,但是,我删除,因为它对于他的代码不起作用,Promise.all将失败,并且不会根据当前代码的结构返回所有服务器的状态,他需要将'serverTest()'改为不拒绝,而是实际解析一个状态 – peteb

回答

1

你要使用Promise.all()要等到许多承诺已经解决,直到继续,但要注意这个警告(重点煤矿)的:

的Promise.all(迭代器)方法返回一个承诺,当 迭代参数中的所有承诺已解决,或拒绝 与第一次通过承诺的原因拒绝时解决。

因此,在您的情况下,您需要确保您传递给.all()的所有承诺都能解决。为此,您可以使用Promise.catch()来处理来自serverTest()函数的拒绝,并继续优雅。

如果onRejected抛出 错误或返回本身被拒绝的Promise,则catch()返回的Promise将被拒绝; 否则,解决了 。

var serverSet = [{ 
 
    "url": "http://doesNotExist.askdex.co", 
 
    "priority": 1 
 
}, { 
 
    "url": "http://tricon.co", 
 
    "priority": 7 
 
}, { 
 
    "url": "http://offline.bing.co", 
 
    "priority": 2 
 
}, { 
 
    "url": "http://google.com", 
 
    "priority": 4 
 
}, { 
 
    "url": "http://yahoo.com", 
 
    "priority": 6 
 
}] 
 

 
function serverTest(url, priority) { 
 
    var options = { 
 
    url: url, 
 
    timeout: 5000 
 
    } 
 
    return new Promise((resolve, reject) => { 
 
    // Always resolve for testing purposes 
 
    resolve({ 
 
     "url": url, 
 
     "priority": priority 
 
    }) 
 
    }) 
 
} 
 

 
function findServer(servers) { 
 
    var build = [] 
 
    var promises = servers.map(server => { 
 
    return serverTest(server.url, server.priority) 
 
     .then(resolve => { 
 
     // Do your validation of resolve here 
 
     build.push(resolve) 
 
     }) 
 
     .catch(error => { 
 
     // By using catch, you ensure this promise chain will continue to 
 
     // resolve as long as you don't throw an error here or return another 
 
     // Promise that will reject 
 
     console.log("Server " + server.url + " failed with : " + error) 
 
     }) 
 
    }) 
 

 
    return Promise.all(promises).then(values => { 
 
    // At this point you know that all your promises have resolved, and 
 
    // the successful ones have added an element to 'build' 
 
    return build 
 
    }); 
 
}; 
 

 
findServer(serverSet).then(result => { 
 
    console.log("result is : " + JSON.stringify(result)) 
 
})

编辑:使用的意见建议,forEachmap()代替+ push(),谢谢。

编辑2:为完整示例添加代码,但修改了serverTest,以便始终解决,以便验证findServer正确填充build数组。

+0

非常感谢建议的修复,但我是仍然遇到同样的问题,这是我的函数调用:findServer(serverSet)。然后(result => {0} {0} {0} (错误=> { } \t \t控制台。日志(“错误是”+错误); \t});'我仍然从我的构建中得到一个空数组,返回查找服务器函数 – Havamere

+0

@Havamere我修改了代码示例以包含'serverTest'函数,但我修改它始终解析,只是为了检查'findServer'正确地填充'build'数组。它似乎只是这样做的,这表明你仍然得到一个空数组的原因是你的'serverTest'由于某种原因而被拒绝。您可以检查您的控制台的日志,因为错误应该打印在那里。 –

+0

@JulienZakaib你应该''return serverTest ...'在'.map'里面 – royhowie