【发布时间】:2016-05-24 09:03:51
【问题描述】:
我想我终于设法在很大程度上将注意力集中在 javascript/ES6 Promises 上。这并不容易!但是这个设计有一些让我困惑的地方。
为什么 Promise 构造函数需要回调?鉴于回调被立即调用,调用者不能直接执行该代码,从而避免一种不必要的“别打电话给我,我会打电话给你”吗?
这是我认为 Promise 用法的原型示例,复制自 Jake Archibald 的 Javascript Promises 教程 http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest ,去掉了 cmets。
它是一个基于 Promise 的 XMLHttpRequest GET 请求包装器:
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();
});
}
对我来说,如果将上面的代码改写如下,使用与我想象的完全不同的承诺类型,使用无参数构造函数和解析/拒绝方法,将更容易理解:
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 在 Promise 方面实现起来并不难。起初我试图让它成为 Promise 的一个实际子类,但由于某种原因我无法让它工作;所以我将它实现为一个简单的工厂函数,它返回一个普通的旧 Promise 对象和几个额外的函数 附加的行为类似于成员函数:
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;
};
那么,为什么 Promise 不是这样设计的呢?我想如果是这样的话,它会帮助我更快地理解 Promise ——我敢打赌它会把我的学习时间缩短一半。
我知道很多聪明人都参与了 Promise API 的制作,而且每个人似乎都普遍为它感到高兴和自豪,所以我想知道他们在想什么。
【问题讨论】:
-
你的“easierToUnderstandPromise”在某种程度上就像 jQuery.Deferred。对于您的设计,返回的承诺必然会公开解析/拒绝方法。我在某处读过为什么这是“坏事”,但我找不到那个资源(我已经读了好几年了)
-
也有延迟模式,不过it's deprecated for good reason
标签: javascript promise es6-promise