2013-04-01 4 views
2

mongoosejs async code.Дождитесь завершения асинхронизации до возврата

userSchema.static('alreadyExists',function(name){ 
    var isPresent; 
     this.count({alias : name },function(err,count){ 
     isPresent = !!count 
     }); 
    console.log('Value of flag '+isPresent); 
    return isPresent; 
}); 

Я знаю isPresent возвращается, прежде чем функция this.count асинхронной вызывает функцию обратного вызова, так что его значение не определено. Но как я жду ответного вызова, чтобы изменить значение isPresent, а затем безопасно вернуться?

какой эффект делает (function(){ asynccalls() asynccall() })(); имеет в потоке асинхронного движения. Что произойдет, если var foo = asynccall() or (function(){})() Ожидают ли эти два возвращения?

process.nextTick() помощь?

Я знаю, что есть много вопросов, как это, но ничего не рассказал о проблеме возвращения до завершения асинхронной

ответ

2

Там нет никакого способа сделать это. Вам нужно изменить подпись своей функции, чтобы выполнить обратный вызов, а не возвращать значение.

Выполнение IO async является одной из основных мотивов Node.js, и ожидание завершения асинхронного вызова приводит к поражению цели.

Если вы дадите мне больше информации о том, чего вы пытаетесь достичь, я могу дать вам указания о том, как реализовать его с помощью обратных вызовов.

Edit: Вам нужно что-то вроде следующего:

userSchema.static('alreadyExists',function (name, callback) { 
    this.count({alias : name}, function (err, count) { 
     callback(err, err ? null : !!count); 
     console.log('Value of flag ' + !!count);  
    }); 
}); 

Затем, вы можете использовать его как:

User.alreadyExists('username', function (err, exists) { 
    if (err) { 
     // Handle error 
     return; 
    } 

    if (exists) { 
     // Pick another username. 
    } else { 
     // Continue with this username. 
    } 
} 
+0

alreadyExists - это функция, которая проверяет, присутствует ли псевдоним, заданный пользователем, в db, если он присутствует, он получает заметку, чтобы выбрать другую. –

+0

Что можно сделать, если они хотят что-то проверить в db, а затем продолжить на основе результатов? –

+0

Спасибо за обновление! , Это очистило много вещей, особенно, как плохо его ждать и мое незнание власти обратных вызовов –

0

была такая же проблема. Я хотел, чтобы мои тесты мокко работали очень быстро (как они это делали ранее), но в то же время, чтобы в моем приложении присутствовал и функционировал слой анти-DOS. Выполнение этих тестов так же, как они первоначально работали, было безумно быстрым, а модуль ddos, который я использовал, начал отвечать с ошибкой Too Many Requests, что привело к сбою тестов. Я не хотел отключать его только для тестовых целей (я действительно хотел иметь автоматические тесты для проверки слишком многих запросов, чтобы они были там).

У меня было одно место, используемое всеми тестами, которые подготовили клиента для запросов HTTPS (заполненных надлежащими заголовками, аутентифицированными, с кукисами и т. Д.). Похоже, это более или менее:

var agent = thiz.getAgent(); 
thiz.log('preReq for user ' + thiz.username); 
thiz.log('preReq for ' + req.url + ' for agent ' + agent.mochaname); 

if(thiz.headers) { 
    Object.keys(thiz.headers).map(function(header) { 
     thiz.log('preReq header ' + header); 
     req.set(header, thiz.headers[header]); 
    }); 
} 
agent.attachCookies(req); 

Так что я хотел, чтобы придать там сон, который будет пинать каждые 5 раз этот клиент был запрошен тест, чтобы выполнить запрос - поэтому весь набор будет работать быстро и каждый 5-й запрос будет ждать, чтобы модуль ddos ​​рассмотрел мою просьбу, не подлежащую отмене ошибкой Too Many Requests.

Я искал большинство записей здесь об Async и других libs или практиках. Все они нуждались в обратном вызове - это означало, что мне пришлось бы переписать пару сотен тестовых случаев.

Наконец-то я отказался от любого элегантного решения и упал на тот, который работал на меня. Который добавлял цикл for, чтобы проверить статус несуществующего файла. Это привело к тому, что операция была выполнена достаточно долго, и я мог ее откалибровать до 6500 мс.

for(var i = 0; i < 200000; ++i) { 
    try { 
     fs.statSync('/path' + i); 
    } catch(err) { 
    } 
}; 
Смежные вопросы