JavaScript Promise API 是否比它需要的更复杂
Is javascript Promise API more convoluted than it needs to be?
我想我终于设法在很大程度上改变了javascript/ES6 Promises。 这并不容易! 但是有一些东西让我对设计感到困惑。
为什么 Promise 构造函数接受回调? 鉴于回调是立即调用的,调用方是否不能只执行该代码,从而避免一个不必要的令人费解的"不要打电话给我,我会打电话给你"?
以下是我认为是 Promise 用法的典型示例,它复制自 Jake Archibald 的 Javascript Promise 教程 http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest,并删除了注释。
它是一个基于 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();
});
}
对我来说,如果按照如下方式重写上面的代码,使用我想象的非常不同的承诺,具有 no-arg 构造函数和解析/拒绝方法,上面的代码会更容易理解:
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;
}
MyEasyToUnderstandingPromise在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 API 的制作,每个人似乎都为此感到高兴和自豪,所以我想知道他们在想什么。
您的版本不是异常安全的,而 Promises/A+ 是安全的,因为它们被 Promise
构造函数捕获。
承诺旨在用作值。 ES 构造函数方法封装了 Promise 的创建,然后可以像值一样传递。 当该值被传递时,该值的使用者不需要resolve
和reject
,因此这些函数不应成为公共 API 的一部分。
(以及所有关于异常处理和链接的内容(
作为辅助信息,当脚本定义 ES6 承诺链时,例如
var promise = new Promise(executor).then(something).catch(handleError);
承诺变量左设置为由 .catch 方法调用返回的承诺。 实际上,整个链或 Promise 对象被执行器函数持有的解析/拒绝函数引用阻止进行垃圾回收。如果调用 solve(通常在执行程序返回之后但在让解析/拒绝函数超出范围之前异步调用(,则调用侦听器then
"某物",Promise 平台内部执行器持有 then
调用返回的承诺的解析/拒绝函数引用,以防止它和任何后续链式承诺过早被垃圾回收。
在建议的延迟模型下,您不能以这种方式设置承诺链,因为您需要引用链中的第一个承诺才能解决或拒绝它。代码变得更像
var promise = new Promise(); // no executor
promise.then(something).catch(handleError);
initiateOperation( promise);
然后在操作响应代码中异步
promise.resolve(value); // if no error occurred
promise = null; // explicit discard of first promise reference to allow GC?
ES6 承诺的一般最小方法现在开始看起来很有希望(哎哟(。我确实同情你在学习承诺如何运作方面的困难——一个有趣的旅程!!
- 使用promise和mongoose对文档进行排序
- 测试Angular Service解决错误回调中的promise
- 在Redux中,我应该在哪里编写复杂的异步流
- 节点协同与生成器和Promise并行流量控制
- 将复杂对象从angular js传递到web api,它总是返回404
- dropdown.js中的复杂事件处理
- 您有更好的动态方式来缩短复杂的代码jquery吗
- 根据是否解析了 Promise 从函数返回值
- 相当复杂的Regex
- 用Javascript重新格式化复杂文本日期字符串的更好方法
- 将一个方法转换为promise:Nodejs
- 函数在promise被解析后被调用,但Jasmine未通过测试.为什么?
- 加速我的复杂函数绘图仪(canvas+javascript)
- JQuery Mobile Javascript复杂方程式
- js promise没有正确关闭
- Angularjs使用“;这个“;promise内的关键字回调
- AngularJS和promise值在调用本地函数时的效果-未定义
- 在ES6 Promise中,我应该在解决/拒绝之前使用return吗
- JavaScript Promise API 是否比它需要的更复杂
- 复杂承诺返回链中的 promise catch() 顺序