11 javascript
我看过很多实现,它们看起来都很不一样,我无法真正提炼出承诺的本质.
如果我不得不猜测它只是一个在回调触发时运行的函数.
有人可以在几行代码中实现最基本的承诺.
例如,从这个答案
片段1
var a1 = getPromiseForAjaxResult(ressource1url);
a1.then(function(res) {
append(res);
return a2;
});
Run Code Online (Sandbox Code Playgroud)
如何传递函数以then了解何时运行.
也就是说,它如何传递回ajax在完成时触发的回调代码.
片段2
// generic ajax call with configuration information and callback function
ajax(config_info, function() {
// ajax completed, callback is firing.
});
Run Code Online (Sandbox Code Playgroud)
这两个片段有何关联?
猜测:
// how to implement this
(function () {
var publik = {};
_private;
publik.then = function(func){
_private = func;
};
publik.getPromise = function(func){
// ??
};
// ??
}())
Run Code Online (Sandbox Code Playgroud)
T.J*_*der 25
从根本上说,一个承诺只是一个对象,它有一个标志,说明它是否已经解决,以及它维护的一系列功能,以便在结算时通知.代码有时可以说不仅仅是单词,所以这里有一个非常基本的,不现实世界的例子,纯粹是为了帮助传达这些概念:
// 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
}
}
};
Run Code Online (Sandbox Code Playgroud)
所以Promise保持状态,以及在承诺结算时调用的函数.解决 promise 的行为通常是Promise对象本身的外部(当然,这取决于实际使用,你可以将它们组合起来 - 例如,与jQuery的ajax[ jqXHR]对象一样).
同样,上述内容纯粹是概念性的,并且缺少必须在任何现实世界的承诺实现中出现的几个重要事项,以使其有用:
then并且settle应该始终异步调用回调,即使承诺已经解决.then应该因为否则调用者不知道回调是否是异步的.settle应该因为回调之前不应该运行回调settle.(ES2015承诺做这两件事.jQuery Deferred没有.)
then并且settle应该确保回调中的失败(例如,异常)不会直接传播到代码调用then或settle.这与上面的#1部分相关,对于下面的#3更是如此.
then应该根据调用回调的结果(然后或稍后)返回一个新的 promise.这对于编写承诺操作非常重要,但会使上述内容复杂化.任何合理的承诺都会实现.
我们需要不同类型的"结算"操作:"解决"(基础操作成功)和"拒绝"(失败).某些用例可能包含更多状态,但已解决和拒绝是最基本的两种状态.(ES2015的承诺已经解决并拒绝.)
我们可以做settle(或单独的resolve和reject)以某种方式私有的,所以只有承诺的创建者可以解决.(ES2015承诺 - 以及其他几个 - 通过让Promise构造函数接受一个接收resolve和reject作为参数值的回调来做到这一点,因此只有该回调中的代码才能解析或拒绝[除非回调中的代码以某种方式使它们公开].)
等等
Ber*_*rgi 11
有人可以在几行中实现最基本的承诺吗?
这里是:
function Promise(fn) {
// takes a function as an argument that gets the fullfiller
var callbacks = [], result;
fn(function fulfill() {
if (result) return;
result = arguments;
for (var c;c=callbacks.shift();)
c.apply(null, arguments);
});
this.addCallback = function(c) {
if (result)
c.apply(null, result)
else
callbacks.push(c);
}
}
Run Code Online (Sandbox Code Playgroud)
附加then链接(您需要答案):
Promise.prototype.then = function(fn) {
var that = this;
return new Promise(function(c){
that.addCallback(function() {
var result = fn.apply(null, arguments);
if (result instanceof Promise)
result.addCallback(c);
else
c(result);
});
});
};
Run Code Online (Sandbox Code Playgroud)
这两个片段有何关联?
ajax从getPromiseForAjaxResult函数中调用:
function getPromiseForAjaxResult(ressource) {
return new Promise(function(callback) {
ajax({url:ressource}, callback);
});
}
Run Code Online (Sandbox Code Playgroud)