【问题标题】:How do you return promises from functions that don't allow for return values without using deferred APIs?在不使用延迟 API 的情况下,如何从不允许返回值的函数返回 Promise?
【发布时间】:2016-01-10 21:01:49
【问题描述】:

几天前我问过Is wrapping a promise in a promise an anti-pattern?,这让我想到了这个。

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

但是对于像 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 任务是异步运行的。这可以使用 Promise 解决。

一种方法是使用延迟(代码来自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 的使用非常令人沮丧。承认这一点似乎很重要,因为 bluebird 甚至在他们的 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 模式的情况?

【问题讨论】:

  • afaik,“延迟”只是作为 jQuery 中的特定事物“弃用”,而不是一般的概念。也就是说,您可以在回调之外做出承诺并从回调内部解决它...
  • 我使用var wait = ms => new Promise(resolve => setTimeout(resolve, ms));,然后在其他地方避免setTimeout,因为它的错误处理特性很差。

标签: javascript node.js promise


【解决方案1】:

您将变量命名为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')));

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

另见:

【讨论】:

  • 我同意这一点,实际上我记得我以前做过几次。出于好奇,有没有办法在不将整个任务包装在承诺中的情况下做到这一点?
  • 但这正是一个承诺。 Promise 是一个值的代理,“我向您承诺一个值(或错误)将在未来的某个时间到达”。所以你基本上需要promise wrapper。通常,最好将整个东西包装在一个函数中并调用它,允许您通过闭包将参数传递给 Promise 构造函数。
  • 是否有可能做这样的事情:jsfiddle.net/zrg01t65/1?显然这个例子实际上不起作用,因为 fiddle 没有 gulp,但是有效吗?
  • 不,您的resolve() 在第二个函数中来自哪里?阅读我链接的第一个问题/答案。
  • 感谢您今天的所有帮助。我最终从上面接受了我破碎的想法并制作了这个:github.com/AriaFallah/pwrap。不确定它会有多大用处,但能够为 npm 制作我的第一个模块真是太好了。感谢您回答所有问题:D
猜你喜欢
  • 2020-04-10
  • 1970-01-01
  • 2019-07-05
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
  • 2011-09-14
  • 2023-03-26
相关资源
最近更新 更多