我看过许多实现,它们看起来如此不同,我无法真正提炼出 promise 的本质。
如果我不得不猜测它只是一个在回调触发时运行的函数。
有人可以在没有外链的情况下用几行代码实现最基本的 promise 吗。
例如来自这个answer
片段 1
var a1 = getPromiseForAjaxResult(ressource1url);
a1.then(function(res) {
append(res);
return a2;
});
传递给 then
的函数如何知道何时运行。
也就是说,它是如何传递回 ajax 完成时触发的回调代码的。
片段 2
// generic ajax call with configuration information and callback function
ajax(config_info, function() {
// ajax completed, callback is firing.
});
这两个片段有什么关系?
猜测:
// how to implement this
(function () {
var publik = {};
_private;
publik.then = function(func){
_private = func;
};
publik.getPromise = function(func){
// ??
};
// ??
}())
最佳答案
从根本上说,promise 只是一个对象,它有一个标志,说明它是否已被解决,以及它维护的一个函数列表,以通知它是否/何时被解决。代码有时胜于 Eloquent ,所以这里有一个非常基本的非真实世界示例,纯粹用于帮助传达概念:
// See notes following the code for why this isn't real-world code
function Promise() {
this.settled = false;
this.settledValue = null;
this.callbacks = [];
}
Promise.prototype.then = function(f) {
if (this.settled) {
f(this.settledValue); // See notes 1 and 2
} else {
this.callbacks.push(f);
}
// See note 3 about `then`
// needing a return value
};
Promise.prototype.settle = function(value) { // See notes 4 and 5
var callback;
if (!this.settled) {
this.settled = true;
this.settledValue = value;
while (this.callbacks.length) {
callback = this.callbacks.pop();
callback(this.settledValue); // See notes 1 and 2
}
}
};
所以 Promise
保存状态,以及在 promise 结算时调用的函数。 解决 promise 的行为通常在Promise
之外对象本身(当然,这取决于实际用途,您可以将它们组合起来——例如,与 jQuery 的 ajax
[ jqXHR
] 对象一样)。
同样,以上内容纯粹是概念性的,缺少一些重要的东西,这些东西必须存在于任何现实世界的 promise 实现中才能发挥作用:
then
和settle
应该总是异步调用回调,即使 promise 已经确定。then
应该,否则调用者不知道回调是否是异步的。settle
应该是因为回调不应该在settle
之后运行已经回来了。 (ES2015 的 promises 做这两件事。jQuery 的Deferred
没有。)then
和settle
应确保回调中的失败(例如异常)不会直接传播到调用then
的代码或settle
.这与上面的第 1 点部分相关,与下面的第 3 点更相关。then
应该根据调用回调的结果返回一个新的 promise(然后,或之后)。这对于组合 promise 化的操作来说是相当基础的,但会使上面的操作明显复杂化。任何合理的 promise 都可以实现。我们需要不同类型的“解决”操作:“解决”(底层操作成功)和“拒绝”(失败)。一些用例可能有更多状态,但解决和拒绝是基本的两个。 (ES2015 的 promise 有 resolve 和 reject。)
我们可能会制作
settle
(或单独的resolve
和reject
)以某种方式私有(private),因此只有 promise 的创建者才能解决它。 (ES2015 promise ——以及其他几个 promise ——通过让Promise
构造函数接受一个接收resolve
和reject
作为参数值的回调来做到这一点,因此只有该回调中的代码可以解析或拒绝 [除非回调中的代码使它们以某种方式公开]。)
等等等等
关于javascript - 概念 - 提炼 promise 如何运作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15668075/