【问题标题】:Filtering out empty API responses to avoid errors过滤掉空的 API 响应以避免错误
【发布时间】:2016-08-04 23:30:49
【问题描述】:

基本上,我制作了一个程序,可以输入单词并使用 Wordnik API 找到它们的定义。然后动态显示每个单词,并在单击时显示定义。这是代码:

function define(arr) {
    return new Promise(function(resolve, reject) {
    var client = [];
    var definitions = {};
    for (var i = 0, len = arr.length; i < len; i++) {
        (function(i) {
            client[i] = new XMLHttpRequest();
            client[i].onreadystatechange = function() { 
                if (client[i].readyState === 4 && client[i].status === 200) {
                    if (client[i].responseText.length === 0) {
                        console.log(client[i].responseText);
                        client.responseText[0] = {
                            word: arr[i],
                            text: 'Definition not found'
                        };
                    } 
                    definitions[arr[i]] = JSON.parse(client[i].responseText);
                    if (Object.keys(definitions).length === arr.length) {
                        resolve(definitions); 
                    } 
                }
            };
            client[i].open('GET', 'http://api.wordnik.com:80/v4/word.json/' + arr[i] +
                '/definitions?limit=1&includeRelated=false&sourceDictionaries=all&useCanonical=false&includeTags=false&api_key=',
                true);
            client[i].send();
        })(i);
    }
});
}

function makeFlashCards() {
    var data = document.getElementById('inputText').value;
    var wordsToDefine = ignore(makeArr(findUniq(data)));
    define(wordsToDefine).then(function(result) {
        success(result);
    }).catch(function(reason) {
        console.log('this shouldnt run');
    });
}

function success(obj) {
    document.getElementById('form').innerHTML = '';
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            addElement('div', obj[prop][0].word);
        } 
    }
    attachDefinition(obj);
}

function addElement(type, word) {
    var newElement = document.createElement(type);
    var content = document.createTextNode(word);
    newElement.appendChild(content);
    var referenceNode = document.getElementById('form');
    document.body.insertBefore(newElement, referenceNode);
    newElement.id = word;
    newElement.className = "flashcards";
}

function attachDefinition(obj) {
    var classArr = document.getElementsByClassName('flashcards');
    for (let i = 0, len = classArr.length; i < len; i++) {
            classArr[i].addEventListener('click', function() {
                cardClicked.call(this, obj);
            });
    }
}

function cardClicked(obj) {
    var el = document.getElementById(this.id);
    if (obj[this.id].length !== 0) {
    if (this.innerHTML.split(' ').length === 1) {
        var img = document.createElement('img');
        img.src = 'https://www.wordnik.com/img/wordnik_badge_a2.png';
        el.innerHTML = obj[this.id][0].text 
            + ' ' + obj[this.id][0].attributionText + '<br>';
        el.style['font-weight'] = 'normal';
        el.style['font-size'] = '16px';
        el.style['text-align'] = 'left';
        el.style['overflow'] = 'auto';
        el.appendChild(img);
    } else {
        el.innerHTML = obj[this.id][0].word;
        el.style['font-weight'] = 'bold';
        el.style['font-size'] = '36px';
        el.style['text-align'] = 'center';
        el.style['overflow'] = 'visible';
    }
}
}

define 函数得到一个包含所有有效单词的数组时,程序会按预期工作,但是如果数组参数中的任何单词无效,则程序不会向每个元素添加点击事件处理程序。我认为这可能与catch 被触发有关。

当请求无效词时,Wordnik API 会返回一个空数组,这可能是此问题的根源。我试图通过添加

来解决这个问题
if (client[i].responseText.length === 0) {
    console.log(client[i].responseText);
    client.responseText[0] = {
        word: arr[i],
        text: 'Definition not found'
    };

但是这个条件永远不会运行。

我需要一些过滤空数组响应的方法,这样catch 就不会被触发并且程序可以顺利运行。

【问题讨论】:

  • 您应该从示例代码中删除您的 API 密钥(如果有效)

标签: javascript arrays promise


【解决方案1】:

当您到达 if (client[i].responseText.length === 0) 时,请确保 client[i].responseText 返回空字符串。可能是undefined 在这种情况下client[i].responseText.length 会抛出一个错误,这将导致catch 块执行。

function makePromise() {
  return new Promise(function(resolve, reject) {
    var test = undefined;
    if (test.length === 0) {
      resolve("resolved");
    }
  });
}

makePromise().then(console.log).catch(function(res) {
  console.log('Error was thrown')
});

尝试将条件更改为:

if (client[i].responseText &amp;&amp; client[i].responseText.length === 0)

【讨论】:

  • 谢谢,不幸的是,这仍然没有触发条件。
  • 实际上它确实触发了我只需要解析 JSON 字符串。
猜你喜欢
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 2016-12-24
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多