2016-06-01 3 views
0

Я работаю над async.waterfall, что я не уверен, как этого избежать: «TypeError: Невозможно прочитать свойство« MediaUrl »undefined». Этот TypeError не возникает при каждом запуске скрипта.Как избежать async.waterfall "TypeError: Невозможно прочитать свойство неопределенного"?

поток выглядит следующим образом:

  1. GetName (случайным образом выбирает имя из списка имен
  2. searchImage (использует поиск Bing API для поиска фотографий, связанных с этим именем
  3. processBotdata (принимает результаты от Bing и случайным образом выбирает один из результатов поиска)

Шаг 3, где происходит выпуск:

function processBotdata (searchData, callback) { 

    var photographer = searchData.photographer // the search name 
    var array  = searchData.array; // search results from bing 
    var randomIndex = Math.floor(Math.random() * array.length); 
    var mediaUrl  = array[randomIndex].MediaUrl; // TypeError here! 
    var sourceUrl  = array[randomIndex].SourceUrl; 
    var searchData   = { 
          photographer, 
          mediaUrl, 
          sourceUrl 
          }; 
    fs.readFile('results.json', function (err, data) { 
    var json = JSON.parse(data); 
    json.push(['search results for ' + photographer + ': ', 
           'mediaUrl: ' + searchData.mediaUrl, 
           'sourceUrl: ' + searchData.sourceUrl]); 

    fs.writeFile("results.json", JSON.stringify(json, null, "\t")); 
    console.log(' ==========> searchData appended to results.json file...') 
    }); 
    console.log(' ==========> searchData has now been processed for upcoming tweet...'); 
    setTimeout(function() { 
     callback(null, searchData); 
     console.log(searchData); 
    }, 5000); 
} 

Я реализовал setTimeout для этой функции, надеясь, что это решит проблему. Я думал, что результаты Bing searchData.array еще не были доступны для обработки, т. Е. Рандомизированы и выбраны в этой функции. Поскольку я новичок в Node.js и JavaScript, я не уверен в своей ошибке программирования здесь. Я видел это post, и мне интересно, связано ли это с массивом поиска Bing, который возвращает 50 лучших результатов.

Обновление: вот как async.waterfall называется:

async.waterfall([ 
    getName, 
    async.retryable([opts = {times: 5, interval: 500}], searchImage), 
    async.retryable([opts = {times: 3, interval: 1000}], processBotdata), 
    async.retryable([opts = {times: 3, interval: 500}], getImage) 
], 
function(error, result) { 
    if (error) { 
     console.error(error); 
     return; 
     } 
}); 
+0

Как вы называете эту функцию 'processBotdata'? Возможно, вы вызываете обратный вызов до получения результата. – rcdmk

+0

Я обновил свое оригинальное сообщение, чтобы помочь уточнить. Я использую требуемый шаблон здесь https://github.com/caolan/async#waterfall – filmplane

+0

Что возвращает 'console.log()' on 'searchData' внутри функции' processBotdata() '? – rcdmk

ответ

0

Наиболее очевидная возможность состоит в том, что нет ни одного объекта на индекс массива, который вы получаете. Поскольку вы собираетесь за случайным индексом, имеет смысл, что некоторые случайные числа попадают в заполненные индексы, другие - нет. Есть ли вероятность, что массив разрежен или что произвольное число, которое вы создаете, вне диапазона, несмотря на ваши попытки с Math.floor?

Я бы проверить первый в любом случае, что-то вроде:

var obj = array[randomIndex]; 
if(obj){ 
// do your stuff 
} 

/*** EDIT НОВОЙ INFO ****/

Основываясь на комментарий, есть шанс, что результаты Bing будет пустой массив, поэтому первое, что вы хотите сделать, это проверить, если это так и «не в состоянии быстро», чтобы async.retryable знать он должен повторить:

function processBotData(searchData, callback){ 
    if(!searchData || !searchData.array || !searchData.array.length) 
     return callback(new Error('No search results')); 
    // continue as before from here 
} 

Обратите внимание, что некоторые люди были бы предпочитаю мой последний чтобы быть чем-то вроде searchData.array.length > 0, но 0 evals как false, поэтому я делаю это так.

+0

Поскольку я новичок в программировании и JavaScript, к сожалению, у меня нет ответа на ваши вопросы. Вот массив результатов поиска: он довольно большой, поэтому размещен здесь: http://pastebin.com/LRgQfmJj Будет ли это считаться разреженным? – filmplane

+1

Нет, не выглядит редким для меня.Редкий массив будет таким, где у вас не было значения для каждого индекса. (например, «[1,2,4, null, 17] будет« разреженным », поскольку arr [3] === null). Тем не менее, было бы неплохо, чтобы console.log каждого из ваших значений «randomIndex», чтобы увидеть, что происходит. Единственная причина, по которой вы получите ошибку, которую вы получаете, - это если 'array [randomIndex]' возвращает значение null или undefined. Поэтому начните отладку этих значений, чтобы узнать, можете ли вы определить шаблон. – Paul

+0

В качестве продолжения я запустил 'console.log' в' var randomIndex = Math.floor (Math.random() * array.length); 'и быстро нашел' randomIndex: 0' 'TypeError: Не могу прочитать свойство 'MediaUrl' of undefined' – filmplane

Смежные вопросы