Модуль обещания NodeJS del нуждается в явной функции для обещания?

Я не понимаю, почему эта функция del нуждается в новой функции для своего обещания. Ниже приведен полный код. Проблема в чистой функции.

gulp.task('styles', ['clean-styles'], function () {
log('Compiling less to css');

return gulp
    .src(config.less)
    .pipe($.less())
    .pipe($.autoprefixer({browsers: ['last 2 version', '> 5%']}))
    .pipe(gulp.dest(config.temp));

});

gulp.task('clean-styles', function (done) {
    var files = config.temp + '**/*.css';
    return clean(files, done);
});

gulp.task('less-watcher', function () {
    gulp.watch([config.less], ['styles']);
});

////////////////

function clean(path, done) {
    log('Cleaning: ' + $.util.colors.blue(path));

    console.log(typeof done); // prints 'function'
    del([path]).then(done); // errors
}

function log(msg) {
    if (typeof msg === 'object') {
        for (var item in msg) {
            if (msg.hasOwnProperty(item)) {
                $.util.log($.util.colors.blue(msg[item]));
            }
        }
    } else {
        $.util.log($.util.colors.blue(msg));
    }
}

Это ошибка, которую я получаю:

[23:28:32] Using gulpfile ~/WebstormProjects/gulp-tutorial/gulpfile.js
[23:28:32] Starting 'clean-styles'...
[23:28:32] Cleaning: ./.temp**/*.css
function
[23:28:32] 'clean-styles' errored after 36 ms
[23:28:32] Error    
at formatError (/usr/lib/node_modules/gulp/bin/gulp.js:169:10)    
at Gulp.<anonymous> (/usr/lib/node_modules/gulp/bin/gulp.js:195:15)    
at emitOne (events.js:96:13)    
at Gulp.emit (events.js:188:7)    
at Gulp.Orchestrator._emitTaskDone (/home/user/WebstormProjects/gulp-tutorial/node_modules/orchestrator/index.js:264:8)    
at /home/user/WebstormProjects/gulp-tutorial/node_modules/orchestrator/index.js:275:23    
at finish (/home/user/WebstormProjects/gulp-tutorial/node_modules/orchestrator/lib/runTask.js:21:8)    
at cb (/home/user/WebstormProjects/gulp-tutorial/node_modules/orchestrator/lib/runTask.js:29:3)

Если я изменю код для "чистой" функции, как показано ниже, это странным образом решит проблему. Почему он отклоняет одну функцию, но принимает другую?

function clean(path, done) {
    log('Cleaning: ' + $.util.colors.blue(path));

    console.log(typeof done); // prints 'function'
    del([path]).then(function () {
        done(); // works!
    });
}

Даже если я использую функцию, которая была назначена переменной, а не была поднята, она все равно работает. Так почему же он не принимает функцию "сделано" в обещании. Это ошеломляет мой мозг.

function clean(path, done) {
    log('Cleaning: ' + $.util.colors.blue(path));

    console.log(typeof done); // prints 'function'
    var test = function () {
        done();
    }
    del([path]).then(test);
}

---------- решаемые ----------

Спасибо Йоханнесу Мерцу за ответ на этот вопрос для меня. Я считал функцию "выполнено" своим обратным вызовом, но я ошибся. Он принадлежит gulp, поэтому для имитации проблемы используйте новую "чистую" функцию ниже.

function clean(path, done) {
    log('Cleaning: ' + $.util.colors.blue(path));

    del([path]).then(function (val) {
        console.log(val);
        done('Not null or undefined so this will fail it');
        // done(); but this would work!
    });
}

Обычно обещание передает аргумент функции, используемой обещанием. Это приводит к ошибкам, потому что обратный вызов "done" считает, что аргумент является сообщением об ошибке или объектом. Это имеет смысл для меня сейчас.

done(err);

Так что, если 'err' равно нулю или не определено, у нас не будет проблем. Проблема в том, что обещание не знает этого. Обещание передает сообщение, а не ошибку, но функция done считает ее ошибкой, поэтому она выдает ошибку.

Задача решена:)

1 ответ

Это потому, что функция del разрешает обещание со значением. Посмотрите документы, выполненные считается успешным, если он передан неопределенным:

https://github.com/gulpjs/gulp/blob/master/docs/API.md#accept-a-callback

Так вы звоните done('some value that isn't undefined') если вы передадите done в блок then, что считается ошибкой, тогда как вы вызываете done(); если вы оберните его в дополнительную функцию. Пытаться

del([path]).then(function (delResult) {
    console.log(delResult);
    done(); // works!
});

чтобы увидеть, что вернулось.

Другие вопросы по тегам