返回承诺的数组

我有以下对象,存储在变量 ( $gameSystem._ipLookupJSON) 中:


{

    "www.geoplugin.net/json.gp?jsoncallback=?": {

        "IP": "geoplugin_request",

        "Country": "geoplugin_countryCode",

        "City": "geoplugin_city"

    },


    "gd.geobytes.com/GetCityDetails?callback=?": {

        "IP": "geobytesipaddress",

        "Country": "geobytescountry",

        "City": "geobytescity"

    },


    "ip-api.com/json": {

        "IP": "ip",

        "Country": "country_name",

        "City": "city"

    },


    "ipinfo.io/json": {

        "IP": "ip",

        "Country": "country",

        "City": "city"

    }

}

此对象中的每个键都是一个 URL。


我有一个函数 ( $._findService()):

  1. 遍历这些键中的每一个并将它们发送到另一个函数 ( $._urlExists()),该函数检查 URL 是否有效/响应,

  2. 如果为 true,则$._findService()创建一个仅包含键及其元素的新数组,

  3. 并且应该返回这个新数组。

不幸的是,我在第三步 - 返回新数组时遇到了问题。

我已经谷歌搜索并尽可能多地阅读关于Promises.thenAsync/Await 的内容,但我就是无法弄清楚,我只能盯着这些代码行看。

const isServiceAvailable = async url_to_check => {

  console.log(url_to_check);

  return await subaybay.an._urlExists("http://" + url_to_check);

};


const checkServices = async(json_data) => {

    return await Promise.all(Object.keys(json_data).map(url_to_check => isServiceAvailable(url_to_check)));

};


$._findService = function(json_data) { 

  var url_check = checkServices(json_data); 

  url_check.then(function(values) { 

    for (i = 0; i < values.length; i++) { 

      if (values[i] === true) { 

        var service_to_use = new Promise(function(resolve, reject) {

          var result = [];

          result.push(json_data[Object.keys(json_data)[i]]);

          result.unshift(Object.keys(json_data)[i]);

          resolve(result);

        });

        service_to_use.then(function(value) {

          console.log(value);

          return value;

        });

      }; 

    }; 

  }); 

};

我希望$._findService()返回一个数组。


但唉,我得到的只是undefined.


如果我的代码不够优雅或不漂亮,我深表歉意——我从 2 月底开始自学 JavaScript。


长风秋雁
浏览 125回答 2
2回答

凤凰求蛊

你的问题是你没有在函数范围内返回任何东西,你应该返回承诺。const isServiceAvailable = url_to_check => subaybay.an._urlExists("http://" + url_to_check);const checkServices = urls => Promise.all(urls.map(url_to_check => {&nbsp; &nbsp; return {url: url_to_check,status: isServiceAvailable(url_to_check)}}));$._findService = async function(json_data) {&nbsp; &nbsp; const values = await checkServices(Object.keys(json_data));&nbsp; &nbsp; return values.filter(v => v.status).map(v => v.url);};然后您可以使用:const result = await $._findService(json_data)或者$._findService(json_data).then(result => { /* Do something */ })注意:当您从异步函数返回某些内容时,您将获得一个承诺,因此,当您使用 await 时,您正在等待内联的承诺结果。在 Promise 上使用 async 和 await 没有也永远不会有任何缺点,而且它是现代和更好的,因为您没有使用“then”或“new Promise”语法创建更多嵌套函数。

绝地无双

我建议对checkServices. 目前,输入类型是一个对象,但输出是数组的承诺。我认为返回对象的承诺会更直观,匹配原始输入 -// old functioncheckServices({ "/foo": ..., "bar": ... })// => Promise [ true, false ]// new functioncheckServices({ "/foo": ..., "bar": ... })// => Promise { "/foo": true, "/bar": false }这是变化——// old functionconst checkServices = async(json_data) => {&nbsp; &nbsp; return await Promise.all(Object.keys(json_data).map(url_to_check => isServiceAvailable(url_to_check)));};// new functionconst checkServices = (o = {}) =>&nbsp; Promise.all(&nbsp; &nbsp; Object.keys(o).map(k =>&nbsp; &nbsp; &nbsp; isServiceAvailable(k).then(v => [ k, v ])&nbsp; &nbsp; )&nbsp; )&nbsp; .then(Object.fromEntries)有了这个结果,很容易找到true一个对象的所有键 -$._findService = (o = {}) =>&nbsp; checkServices(o).then(o =>&nbsp; &nbsp; Object.keys(o).filter(k => o[k])&nbsp; )$._findService({ "/foo": ..., "bar": ... })// Promise [ "/foo" ]展开下面的代码片段以在浏览器中运行此程序 -const checkServices = (o = {}) =>&nbsp; Promise.all(&nbsp; &nbsp; Object.keys(o).map(k =>&nbsp; &nbsp; &nbsp; isServiceAvailable(k).then(v => [ k, v ])&nbsp; &nbsp; )&nbsp; )&nbsp; .then(Object.fromEntries)// fake implementation for democonst isServiceAvailable = (service = "") =>&nbsp; new Promise (r =>&nbsp; &nbsp; setTimeout (r, 1000, service === "/foo")&nbsp; )_findService = (o = {}) =>&nbsp; checkServices(o).then(o =>&nbsp; &nbsp; Object.keys(o).filter(k => o[k])&nbsp; )checkServices({ "/foo": 1, "/bar": 2 }).then(console.log, console.error)// { "/foo": true, "/bar": false }_findService({ "/foo": 1, "/bar": 2 }).then(console.log, console.error)// [ "/foo" ]async-await在这个程序中使用没有任何好处
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript