为了账号安全,请及时绑定邮箱和手机立即绑定

返回承诺的数组

返回承诺的数组

长风秋雁 2021-06-14 17:59:19
我有以下对象,存储在变量 ( $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()):遍历这些键中的每一个并将它们发送到另一个函数 ( $._urlExists()),该函数检查 URL 是否有效/响应,如果为 true,则$._findService()创建一个仅包含键及其元素的新数组,并且应该返回这个新数组。不幸的是,我在第三步 - 返回新数组时遇到了问题。我已经谷歌搜索并尽可能多地阅读关于Promises、.then和Async/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。
查看完整描述

2 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

你的问题是你没有在函数范围内返回任何东西,你应该返回承诺。


const isServiceAvailable = url_to_check => subaybay.an._urlExists("http://" + url_to_check);


const checkServices = urls => Promise.all(urls.map(url_to_check => {

    return {url: url_to_check,status: isServiceAvailable(url_to_check)}

}));


$._findService = async function(json_data) {

    const values = await checkServices(Object.keys(json_data));

    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”语法创建更多嵌套函数。


查看完整回答
反对 回复 2021-06-24
?
绝地无双

TA贡献1946条经验 获得超4个赞

我建议对checkServices. 目前,输入类型是一个对象,但输出是数组的承诺。我认为返回对象的承诺会更直观,匹配原始输入 -


// old function

checkServices({ "/foo": ..., "bar": ... })

// => Promise [ true, false ]


// new function

checkServices({ "/foo": ..., "bar": ... })

// => Promise { "/foo": true, "/bar": false }

这是变化——


// old function

const checkServices = async(json_data) => {

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

};


// new function

const checkServices = (o = {}) =>

  Promise.all(

    Object.keys(o).map(k =>

      isServiceAvailable(k).then(v => [ k, v ])

    )

  )

  .then(Object.fromEntries)

有了这个结果,很容易找到true一个对象的所有键 -


$._findService = (o = {}) =>

  checkServices(o).then(o =>

    Object.keys(o).filter(k => o[k])

  )


$._findService({ "/foo": ..., "bar": ... })

// Promise [ "/foo" ]

展开下面的代码片段以在浏览器中运行此程序 -

const checkServices = (o = {}) =>

  Promise.all(

    Object.keys(o).map(k =>

      isServiceAvailable(k).then(v => [ k, v ])

    )

  )

  .then(Object.fromEntries)


// fake implementation for demo

const isServiceAvailable = (service = "") =>

  new Promise (r =>

    setTimeout (r, 1000, service === "/foo")

  )


_findService = (o = {}) =>

  checkServices(o).then(o =>

    Object.keys(o).filter(k => o[k])

  )


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在这个程序中使用没有任何好处


查看完整回答
反对 回复 2021-06-24
  • 2 回答
  • 0 关注
  • 124 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信