返回承诺的数组

时间:2019-06-09 00:19:56

标签: javascript async-await es6-promise rpgmakermv

我将以下对象存储在变量($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. 并且应该返回这个新数组。

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

我拥有Google,并且会尽我所能阅读有关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。

2 个答案:

答案 0 :(得分:1)

您的问题是,您没有在函数范围内返回任何内容,而应该返回了promise。

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结果。

使用异步和在Promise上等待没有任何缺点,而且永远不会有任何不利之处,而且由于您不必使用“ then”或“ new Promise”语法编写更多的嵌套函数,因此它是现代且更好的。

>

答案 1 :(得分:0)

我建议对checkServices稍作更改。当前,输入类型是一个对象,但输出是array的promise。我认为返回对象的Promise与原始输入相匹配会更直观-

// 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没有好处

相关问题