Генератор yoman: копия или шаблон не работают внутри асинхронного обратного вызова

Внутри генератора йоменов я пытаюсь сделать условную копию в зависимости от состояния внешнего сетевого ресурса. Моя проблема в том, что команда yeoman copy (в этом отношении тоже src.copy и template), похоже, ничего не делает при вызове внутри асинхронного обратного вызова, например, из http-запроса.

Пример кода внутри блока yoman.generators.NamedBase.extend:

main: function(){  
//-> here this.copy('inlocation','outlocation') works as expected
var that = this;

var appName = ...
var url = ...

var req = http.request(url, function(res){
//-> here that.copy('inlocation','outlocation') DOES NOT work
    res.on('data', function (data) {
        //console.log('Response received, onData event');
        //-> here that.copy('inlocation','outlocation') DOES NOT work
    });
    //-> here that.copy('inlocation','outlocation') DOES NOT work
});
req.on('error',function(error){
    //...
});
req.end();
//-> here this.copy('inlocation','outlocation') works as expected, once again

Обратите внимание на места, отмеченные комментариями '//-->', для точек отсчета - когда это работает, это работает так, как ожидалось. Когда это не так, на консоль вообще ничего не выводится (так что that.copy, кажется, существует как функция, на самом деле я могу утверждать, что typeof that.copy === 'функция'!), никаких сообщений об ошибках, просто нет файла created (отсутствует и обычное сообщение о создании файла, что характерно для корректно работающей команды).

Использование call или apply для передачи явной ссылки this на функции не изменило поведение, равно как и привязка this к асинхронным функциям.

Каково объяснение такого поведения и как я могу выполнять вызовы копирования таким асинхронным способом?


person doldt    schedule 22.10.2014    source источник
comment
Вы должны ответить на свой вопрос с решением, которое вы нашли. Это поможет другим пользователям идентифицировать ваш вопрос как решенный... и вознаградит вашу работу репутацией.   -  person Eric MORAND    schedule 22.01.2015


Ответы (1)


Согласно комментарию Эрика МОРАНДА, я опубликую решение, которое я нашел, как отдельный ответ, а не редактирование исходного сообщения, надеюсь, его будет легче найти:

Я нашел решение, используя функцию async() йомена RunContext. (см. документацию по API здесь) Следующая строка в начале асинхронного кода:

var done = this.async();

затем вызов done() прямо перед тем, как я захотел запустить копию, заставил ее вести себя так, как ожидалось изначально.

person doldt    schedule 23.01.2015