【问题标题】:Immediately return a resolved promise using AngularJS使用 AngularJS 立即返回一个已解决的承诺
【发布时间】:2014-09-07 18:53:41
【问题描述】:

我正在努力理解 JavaScript(尤其是 AngularJS)中的承诺。

我在服务中有一个函数,我们称之为fooService,它检查我们是否加载了一些数据。如果有,我只希望它返回,如果没有,我们需要加载数据并返回一个 Promise:

this.update = function(data_loaded) {
    if (data_loaded) return;  // We've loaded the data, no need to update

    var promise = Restangular.all('someBase').customGet('foo/bar').then(function(data) {
        // Do something with the data here
    }

    return promise;
}

我有另一个函数,然后像这样调用fooServiceupdate 函数:

fooService.update(data_loaded).then(function() {
    // Do something here when update is finished
})

我的问题是,如果我们不需要在 update 函数中加载数据,则不会返回承诺,因此在我的其他函数中不会调用 .then()。这里应该采用什么方法 - 基本上,如果我们不需要从 Restangular 调用中获取数据,我想立即从 update() 函数返回已解决的承诺?

【问题讨论】:

    标签: javascript angularjs promise restangular angular-promise


    【解决方案1】:

    由于您的 promise 使用与 JavaScript 原生语法相同的语法,您可以使用并返回已解析的 JavaScript promise:Promise.resolve()

    return(Promise.resolve("MyReturnValue"));
    

    【讨论】:

    • 这就是我想要的答案;我有一个价值;它已经准备好了,我只想将它包装在 Promise 中以满足期望 Promises 的 API ... Promise ,我立即解决了(用文字)“
    • 这也是我想要的。我有一个对象,只需要返回一个承诺,因为这是 API 所期望的。
    • 注意这个答案的 IE 支持。 $q 提供跨浏览器支持
    • @JosefE.,关于 IE 支持的要点。理想的答案将解决现代 Javascript 案例(在现代浏览器中或使用转译器)和遗留案例。让我们向微软诸神祈祷,IE 很快就会过时。
    【解决方案2】:

    当前接受的答案过于复杂,滥用deferred anti pattern。这是一个更简单的方法:

    this.update = function(data_loaded) {
        if (data_loaded) return $q.when(data);  // We've loaded the data, no need to update
    
        return Restangular.all('someBase').customGet('foo/bar')
                                 .then(function(data) {
            // Do something with the data here 
        });
    };
    

    或者,更进一步:

    this._updatep = null;
    this.update = function(data_loaded) { // cached
        this._updatep = this._updatep || Restangular.all('someBase') // process in
                                                    .customGet('foo/bar'); //.then(..
        return this._updatep;
    };
    

    【讨论】:

    • 感谢您的提示。我总是错过Kris Kowal's QQ(initialVal) 语法,应该知道$q.when(data) 可以做同样的伎俩。
    【解决方案3】:

    AngularJS 的$q 服务将在这里为您提供帮助。它很像Kris Kowal's Q promise 库。

    当您有一个可能返回承诺或值的异步方法时,请使用$q.when 方法。它将接受传递给它的任何内容,无论是承诺还是值,并创建一个承诺,该承诺将根据传递的承诺被解析/拒绝,或者如果传递了值则被解析。

    $q.when( fooService.update(data_loaded) ).then(function(data){
       //data will either be the data returned or the data
       //passed through from the promise
    })
    

    然后在你的更新函数中返回数据而不是仅仅返回

    if (data_loaded) return data_loaded;
    

    【讨论】:

      【解决方案4】:

      类似于Elo's answer,您可以使用 async/await 语法返回已解决的承诺:

      this.update = async (data_loaded) => {
      
          if (data_loaded) 
              return await null;  // Instead of null, you could also return something else
                                  // like a string "Resolved" or an object { status: 200 }
          else 
              return await OtherPromise();
      }
      

      【讨论】:

        【解决方案5】:

        您可以像这样使用$q.defer()

        this.update = function (data_loaded) {
            var deferred = $q.defer();
        
            if (data_loaded) {
                deferred.resolve(null); // put something that your callback will know the data is loaded or just put your loaded data here.
            } else {
                Restangular.all('someBase').customGet('foo/bar').then(function(data) {
                    // Do something here when update is finished
                    deferred.resolve(data);
                }
            }
        
            return deferred.promise;
        };
        

        希望这会有所帮助。

        【讨论】:

        • 我不知道这是怎么被两次投票的,这是延迟反模式,可以大大简化。
        • 这不仅是延迟的反模式,它也无法传播错误。
        • @Benjamin 恕我直言,这与延迟反模式不完全相同。您提到的延迟反模式是可以完全删除延迟而不会丢失功能。但是,是的,您的答案要简单得多,并且可以很好地处理错误。
        • @samtuner 请接受本杰明的回答而不是这个。
        • @Bergi imo 此解决方案的最大问题是,如果在返回数据之前多次调用此方法,它将发出多个请求而不是一个请求,因为数据被缓存而不是承诺,并且没有“已发送”标志。错误处理也是一个大问题,所以你就在那里。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-25
        • 1970-01-01
        • 1970-01-01
        • 2013-05-15
        • 2014-06-27
        • 2016-07-20
        • 2013-12-31
        相关资源
        最近更新 更多