如何避免async.waterfall" TypeError:无法读取未定义的属性"?

时间:2016-06-01 00:05:24

标签: javascript node.js asynchronous

我正在研究async.waterfall,我不确定如何避免:" TypeError:无法读取属性' MediaUrl'未定义"。每次运行脚本时都不会发生此类型错误。

流程如下:

  1. getName(从名单列表中随机选择一个名称
  2. searchImage(使用Bing搜索API搜索与该名称相关的照片
  3. processBotdata(从Bing获取结果并随机选择其中一个搜索结果)
  4. 步骤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;
          }
    });
    

1 个答案:

答案 0 :(得分:0)

最明显的可能性是你得到的数组索引没有对象。由于您正在追踪随机索引,因此有些随机数会影响填充的索引,而其他随机数则不会。尽管您尝试使用Math.floor,但阵列是否稀疏或者您生成的随机数是否超出范围?

我在任何情况下都先检查,例如:

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

/ ***编辑新信息**** /

根据评论,Bing结果可能是一个空数组,所以你要做的第一件事就是测试是否是这种情况并且'快速失败& #39;让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则认为是假的,所以我这样做。