2016-10-20 5 views
0

Я понимаю, почему я получаю эту ошибку, однако я понятия не имею, как это исправить. Это моя первая функция выглядит так:Async waterfall return 'Callback уже был вызван'

Все, что я делаю, делает запрос на получение всех моих URL-адресов, которые хранятся в базе данных, а затем для каждого ответа на URL-адрес, я просматриваю тело и сохраняю значения информация по телефону saveInformation(value) или saveInfoTwo(value)

function getUrlInfo(urls, callback) { 
    urls.map(function(url) { 
     request.get(urls, { 
      timeout: 1500 
     }, function(error, response, body) { 
      if (error) {console.log(error); 
      } else { 
       parseString(body, function(error, result) { 
        if (error) {console.log(error); 
        } else { 
         result.Values.forEach(function(listValues) { 
          listValues.forEach(function(value) { 
           saveInformation(value); 
          }); 
          saveInfoTwo(value); 
         }); 
        } 
       }); 
      } 
      callback(null); 
     }); 
    }); 
} 

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

async.waterfall([ 
    getUrls, 
    getUrlInfo 
], function(err, result) { 
    mongoose.connection.close(); 
}); 

Где getUrls это просто метод, который ищет все ссылки и добавляет их к urls, так что getUrlInfo может использовать его.

function getUrls(callback) { 
    var urls = []; 
    urlSchema.find(function(error, data) { 
     data.forEach(function(result) { 
      clusters.push(result.url); 
     }); 
     callback(null, urls); 
    }); 
} 

Я использую mongodb в качестве базы данных.

Это отлично работает, когда есть только один URL-адрес. Как только я добавить еще один URL, я получаю эту ошибку:

Error: Callback was already called. 

Теперь, после попытки отладить, похоже, все работает отлично для первого URL, а затем, когда второй URL заканчивает идти через Еогеасп петли, ошибка возникает.

Как это исправить?

Я уверен, что обратный вызов в моем getUrlInfo() ждет завершения всех строк и циклов foreach, а затем продолжается? - Это не так, я думаю.

Любая помощь будет оценена!

Подводя итог: Как предотвратить появление ошибки при добавлении другого URL-адреса?

+0

Ну, не используйте 'urls.map' который является цикл, который будет * * называть' callback' несколько раз? – Bergi

+1

Вместо этого используйте 'async.map (urls, ..., callback)' – Bergi

+0

Не могли бы вы показать нам 'getUrls'? Вероятно, он вызывает обратный вызов более одного раза. – GilZ

ответ

0

Ваша карта вызывает функцию для первого URL-адреса, когда она заканчивается, вызывается callback. Когда второй выполняется, когда он закончится, он снова вызовет callback, таким образом, вы получите эту ошибку.

Решение, дождитесь окончания всех URL-адресов и последующего вызова.

Как сказал @Bergi на комментарии вы можете использовать async map

function getUrlInfo(urls, callback) { 
    async.map(urls, function(url, cb) { 
     //do what you must 
     cb(); 
    }, callback); 
}