2014-02-12 2 views
5

Это то, что я хочу: у меня есть большой массив, называемый результатами. Каждый элемент в этом массиве я хочу добавить в свою итерационную функцию и сохранить ее в моем mongoDB (здесь также не указаны некоторые шаги, которые не важны). После того, как каждый из этих элементов был сохранен в базе данных (или отказался), я хочу, чтобы console.log отображал «Все сделано». К сожалению, все сделанные изображения отображаются почти сразу после вызова серии, а все остальное все еще обрабатывается. Как мне это сделать правильно?node.js async.eachSeries вызывает окончательный обратный вызов слишком рано

Я использую mongoose с моделью под названием «свет» и для удобства чтения. Я пропустил все сообщения об ошибках из кода. Я использую узел Асинхра для eachSeries части

var async = require('async');  
var results = [very big array] 
var iteration = function(row,callbackDone) { 
    light.find({data: row.data}, function (err,entry) { 
    if(entry.length) { 
     callbackDone(); 
     return console.log(entry + ' already exists'); 
    } 
    var newEntry = new light(row); 
    newEntry.save(function (err,doc) { 
     console.log(entry + ' saved'); 
     callbackDone(); 
    }); 
    }); 
}; 

async.eachSeries(results,iteration, function (err) { 
    console.log('All done'); 
}); 
+1

Попробуйте добавить некоторые регистраторы ошибок ('если (ERR) console.log (ERR);'). – maxdec

+0

Я удалил регистраторы ошибок для удобочитаемости. извините, если я не был чист. Массив легко содержит более 100 записей, операции мангуста работают безупречно, но все это сохраняется после того, как отображается console.log («все сделано»). Мне нужен способ показать «все сделано» точно после того, как все элементы в моем массиве обработаны – elmalto

ответ

4

(ответ, не комментарий, потому что текст был слишком долго ...)

Я использую асинхра что-то слишком и ваш вопрос озадачил меня. Я попробовал код ниже, получив результаты еще дальше. Это сработало для меня. (асинхронизация 0,2,9). Даже изменение задержек на тайм-аут до 0.

Единственное, что выглядело нечетным, было то, что информация о консоли на печатной консоли if(entry.length) после обратного вызова. Если вы получали много сообщений «уже существует», я мог видеть, что они могут появиться позже, но это не похоже на то, что вы описываете.

var async = require('async'); 
var console = require('console'); 
var results = [ ]; 
results.push({id:1,data:'a'}); 
results.push({id:2,data:'b'}); 
results.push({id:3,data:'c'}); 
results.push({id:4,data:'d'}); 

function doFind(obj, callback) { 
    setTimeout(function() { 
    console.log("finding id=" + obj.data.id); 
    obj.data.length = obj.data.id % 2; 
    callback(null, obj.data); 
    }, 500); 
} 

function light(obj) { 
    this.id = obj.id; 
    this.data = obj.data; 
    this.save = function(callback) { 
    setTimeout(function() { 
     console.log("saving id=" + obj.id); 
     callback(null, this); 
    }, 500); 
    }; 
} 

var iteration = function(row,callbackDone) { 
    doFind({data: row}, function (err,entry) { 
    if(entry.length) { 
     callbackDone(); 
     return console.log('id=' + entry.id + ' already exists'); 
    } 
    var newEntry = new light(row); 
    newEntry.save(function (err,doc) { 
     console.log('id=' + entry.id + ' saved'); 
     callbackDone(); 
    }); 
    }); 
}; 

async.eachSeries(results, iteration, function (err) { 
    console.log('All done'); 
}); 

Результаты

finding id=1 
id=1 already exists 
finding id=2 
saving id=2 
id=2 saved 
finding id=3 
id=3 already exists 
finding id=4 
saving id=4 
id=4 saved 
All done 
+0

ваш пример отлично работает и для меня, по какой-то причине я не мог решить свою собственную проблему. Я переключился на var stream = light.find ({}). Stream(); и остановил поток до тех пор, пока не появится асинхронный отклик. Наверное, немного уродливо, но это работает для меня. Большое спасибо за ваш вклад! – elmalto

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