首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >javascript承诺API是否比它所需要的更复杂?

javascript承诺API是否比它所需要的更复杂?
EN

Stack Overflow用户
提问于 2016-02-13 03:27:14
回答 3查看 257关注 0票数 5

我想我最终还是把注意力集中在javascript/ES6的承诺上了。这可不容易!但有件事让我对这个设计感到困惑。

为什么允诺构造函数接受回调?考虑到回调是立即调用的,调用方不能直接执行该代码,从而避免不必要的“不要打电话给我,我会打电话给您”这一不必要的级别吗?

下面是我认为的承诺使用的典型例子,它是从Javascript的Javascript承诺教程http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest中复制的,注释被去掉了。

它是一个基于承诺的包装器,用于XMLHttpRequest GET请求:

代码语言:javascript
复制
function get(url) {
  return new Promise(function(resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', url);
    req.onload = function() {
      if (req.status == 200) {
        resolve(req.response);
      }
      else {
        reject(Error(req.statusText));
      }
    };
    req.onerror = function() {
      reject(Error("Network Error"));
    };
    req.send();
  });
}

对我来说,如果按照下面的方式重写上面的代码,使用我想象中的一种非常不同的承诺,有一个no-arg构造函数和解析/拒绝方法,那么它就更容易理解了:

代码语言:javascript
复制
function get(url) {
  var promise = new MyEasierToUnderstandPromise();
  var req = new XMLHttpRequest();
  req.open('GET', url);
  req.onload = function() {
    if (req.status == 200) {
      promise.resolve(req.response);
    }
    else {
      promise.reject(Error(req.statusText));
    }
  };
  req.onerror = function() {
    promise.reject(Error("Network Error"));
  };
  req.send();
  return promise;
}

就承诺而言,MyEasierToUnderstandPromise并不难实现。起初,我试图使它成为一个实际的承诺子类,但由于某些原因,我无法让它工作;因此,我将它实现为一个简单的工厂函数,它返回一个简单的旧承诺对象,并附加了几个附加的函数,这些函数的行为类似于成员函数:

代码语言:javascript
复制
function NewMyEasierToUnderstandPromise() {
  var resolveVar;
  var rejectVar;
  var promise = new Promise(function(resolveParam, rejectParam) {
    resolveVar = resolveParam;
    rejectVar = rejectParam;
  });
  promise.resolve = resolveVar;
  promise.reject = rejectVar;
  return promise;
};

为什么承诺不是这样设计的呢?我想如果是这样的话,它会帮助我更快地理解承诺--我打赌它会把我的学习时间减少一半。

我知道很多聪明人都参与了这个承诺API的开发,每个人似乎都对此感到高兴和自豪,所以我想知道他们在想什么。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-13 03:34:36

您的版本并不是异常安全的,而承诺/A+是安全的,因为它们被Promise构造函数捕获。

票数 6
EN

Stack Overflow用户

发布于 2016-02-13 04:53:53

承诺是用来作为价值的。ES构造函数方法封装了承诺的创建,然后可以像值一样传递承诺。当传递该值时,该值的使用者不需要resolvereject,因此这些函数不应该是公共API的一部分。

(以及所有关于异常处理和链接的内容)

票数 5
EN

Stack Overflow用户

发布于 2016-02-13 04:28:23

作为辅助信息,当脚本定义ES6承诺链时,如下所示

代码语言:javascript
复制
var promise = new Promise(executor).then(something).catch(handleError);

允诺变量被设置为.catch方法调用返回的承诺。整个链或允诺对象实际上不会被executor函数所持有的“解析/拒绝”函数引用收集到垃圾。如果解析被调用(通常是在执行器返回之后,但在让解析/拒绝函数超出范围之前),则调用then侦听器“being”,其中一个承诺平台内部执行器将为then调用返回的承诺保存解决/拒绝函数引用,以防止它和任何后续链接的承诺本身过早地被垃圾收集。

在延迟模型下,您不能以这种方式设置承诺链,因为您需要引用链中的第一个承诺来解决或拒绝它。代码变得更像

代码语言:javascript
复制
var promise = new Promise(); // no executor
promise.then(something).catch(handleError);
initiateOperation( promise);

然后在操作响应代码中异步执行。

代码语言:javascript
复制
promise.resolve(value);  // if no error occurred
promise = null;          // explicit discard of first promise reference to allow GC?

ES6承诺的一般最小化方法现在看起来很有希望(哎哟)。我很同情你在学习承诺是如何工作的困难-一个有趣的旅程!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35375730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档