【问题标题】:What does a resolve in a promise do exactly?Promise 中的 resolve 究竟做了什么?
【发布时间】:2017-10-20 05:19:28
【问题描述】:

我开始学习 Javascript 中的 Promise,但我仍然没有完全理解它。下面的代码大部分是真实的代码。我已经放置了几个调试器语句,所以程序停止,我可以理解流程是如何工作的并检查一些变量。我已经阅读了一些关于承诺的博客文章,但我仍然无法理解所有内容。这是来自使用 AngularJS 和 q 库的应用程序。

几个问题:
1- deferred.Resolve() 究竟做了什么? response.data 有什么作用?当我检查 'deferred' 对象及其 'promise' 对象时,我看不到 response.data 的任何踪迹。

2- 当我在调试器 #1 之后恢复执行时,我认为 http post 语句会运行,但执行跳转到了 return 语句。我猜这就是promise 跳入的地方,并且该帖子将来会发生?

3- 当函数返回时,我如何知道帖子何时发布?调用者将获得返回承诺,调用者期望如何处理它?

this.GetData = function() 
  {
    var data = blahblah;
    var deferred = this.$q.defer();
    debugger;  //1
    this.$http.post(someurl, data,
               {
                  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                              handleErrors: false
                           })
                            .then(function(response) {
                                debugger; //2
                               (domesomething...)
                               deferred.resolve(response.data);
                            },
                             function(error) {
                              (logerror...)
                              deferred.reject(error);

                });
                debugger; //3
                return deferred.promise;
    };

【问题讨论】:

  • 调试异步代码并不简单。此外,随机缩进使调试更加困难
  • 另外,你正在创建一个 deferred - 但你的 this.$http.post 无论如何都会返回一个承诺 - 避免延迟反模式

标签: javascript promise q


【解决方案1】:

在包装回调样式代码时使用q.defer()(显式创建一个promise)是合适的,“promisifying”...

this.timeoutWithAPromise = function(msec) {
  let defer = q.defer();
  setTimeout(() => defer.resolve(), msec);
  return defer.promise;
};

前面说:“创建一个promise并立即返回它。当msec过去时,该promise将被实现。

问题 1:resolve() 履行了承诺,调用 then() 设置的任何函数,并将传递给解析的任何参数传递给它。

问题 2:你是对的,异步操作已开始,并立即返回完成的承诺。

问题 3a:一旦发出调用,帖子就会在另一个线程上开始(或者超时将在我的例子中开始)。它将在此调用线程上同时继续执行,直到它完成,您从问题 1 中理解,它是通过解析 promise 来完成的,调用它是 then()

问题 3b:调用者如何处理返回的承诺?附加一个你希望在完成后运行的块,可能是额外的异步操作。以我为例……

let self = this;
self.timeoutWithAPromise(1000).then(()=> {
    console.log('1000msec have passed');
    return self.timeoutWithAPromise(1000);
}).then(()=> {
    console.log('now, another 1000msec have passed');
    // ...

重写你的例子,意识到 $http 已经符合承诺......

var data = blahblah;
let headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
let config = { headers: headers, handleErrors: false };
let httpPromise = this.$http.post(someurl, data, config).then((response)=> {
    console.log('got a response. tell our caller about it');
    return response.data;
}).catch((error)=>
    console.log('got an error.  either handle it here or throw it');
    throw error;
});
// this is important:  return the httpPromise so callers can chain off of it
return httpPromise;

现在调用者可以说:

let promiseToDoEvenMore = this.GetData().then((data)=> {
    console.log(data);
    return this.GetMoreData();  // etc.
});
return promiseToDoEvenMore;   // and so on

【讨论】:

    猜你喜欢
    • 2012-07-23
    • 2016-09-10
    • 2023-03-15
    • 2012-10-17
    • 2021-06-04
    • 1970-01-01
    • 2018-07-30
    • 2019-10-06
    • 2021-01-01
    相关资源
    最近更新 更多