如何在不使用延迟API的情况下从不允许返回值的函数返回承诺?

时间:2016-01-10 21:01:50

标签: javascript node.js promise

几天前我问Is wrapping a promise in a promise an anti-pattern?导致我这样做。

在这种情况下,我必须处理setTimeout,它不允许返回值。值得庆幸的是,你可以使用内置的delay函数来处理这个问题(至少对于蓝鸟的承诺)。

但是像gulp任务那样呢?同样受到另一个问题的启发:How to pass an object from gulpfile to another JavaScript file in nodejs?

var stuff;
gulp.task('LoadYamlFiles', function() {
  // do stuff
  stuff = 'blah';
});

module.exports = { stuff };

出口不会是“等等”。因为gulp任务是异步运行的。这可以使用承诺来解决。

你可以做的一种方法是使用延迟(来自https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns的代码):

// setTimeout that returns a promise
function delay(ms) {
    var deferred = Promise.pending();
    setTimeout(function(){
        deferred.resolve();
    }, ms);
    return deferred.promise;
}

根据他们的wiki,这实际上并不被认为是一种反模式,但我发现deferred的用法很多都让人气馁。这似乎很重要,因为蓝鸟在他们的API中甚至不再使用.pending()方法,这意味着即使我愿意,我也不能这样做。

但是你无法做到:

var stuff;
var myPromise = gulp.task('LoadYamlFiles', function() {
  return new Promise(function(resolve, reject) {
    // do stuff
    stuff = 'blah';
    resolve(stuff);
  })
});

module.exports = { myPromise };

因为匿名函数的返回值不是myPromise将包含的内容。此外,它会导致您在此处看到的问题Does a gulp task have to return anything?

那么你如何处理这些通常会使用事实上弃用的deferred模式的情况?

1 个答案:

答案 0 :(得分:4)

你将你的变量命名为myPromise,这是第一个提示,即=的另一边,它应该是一个承诺。那么让我们从

开始吧
var myPromise = new Promise((resolve, reject) => {
  // todo
});

module.exports { myPromise };

现在,让我们填写详细信息。

var myPromise = new Promise((resolve, reject) => {
  gulp.task('LoadYamlFiles', function() {
    let stuff = 'blah';
    resolve(stuff);
  });
});

一些重构给了我们

let myPromise = new Promise(resolve => 
  gulp.task('LoadYamlFiles', () => resolve('blah')));

我确信这不是一个真正的用例,但它仍然适用。

另见: