承诺A +实现:当调用then()并且承诺仍然未决时该怎么办?

时间:2016-01-07 20:13:12

标签: javascript promise

我已经有一段时间与承诺实施一起工作了。

所以我决定实现我自己的诺言库,只是为了好玩(并在过程中学习一些东西)。

我试图遵循Promise A+规范(也许我会留下一些细节,因为我并不意味着将其作为生产代码)。

我的完整代码(仍在进行中)位于此gist,但相关部分如下所示。

我遇到了实施then()的问题。当承诺未决时,我根本不知道该怎么做:

Promise.prototype.then = function(onFulfill, onReject) {
    var ret;
    var self = this;

    if (isFulfilled.call(this)) {
        console.log('fulfilled');
        if (isFunction(onFulfill)) {
            return promiseResolution(this, onFulfill(this.value));
        } else {
            return new Promise(function(resolve){
                resolve(self.value);
            });
        }
    } else if (isRejected.call(this)) {
        console.log('rejected');
        if (isFunction(onReject)) {
            return promiseResolution(this, onReject(this.reason));
        } else {
            return new Promise(function(resolve, reject){
                reject(self.reason);
            });
        }
    } else if (isPending.call(this)) {
        console.log('pending');
        enqueueCallback(this.fulfillCallbackQueue, onFulfill);
        enqueueCallback(this.rejectCallbackQueue, onReject);
        // ... what now?
    }
};

function promiseResolution(promise, x) {
    if (promise === x) {
        throw new TypeError('Cannot resolve promise with itself');
    } else if (x instanceof Promise) {
        if (isFulfilled.call(x)) {
            return new Promise(function(resolve, reject){
                resolve(x.value);
            });
        } else if (isRejected.call(x)) {
            return new Promise(function(resolve, reject){
                reject(x.reason);
            });
        } else {
            return x;
        }
    } else {
        return new Promise(function(resolve, reject){
            resolve(x);
        });
    }
}

答案必须非常明显,但我在这里有点被束缚了。

编辑:

我已经用我正在写的测试套件更新了要点。

编辑#2:

我能够成功运行第一次实现的测试。这是git repository,我存储了我的代码。我会尝试不断改进它。

感谢@BenjaminGruenbaum。

1 个答案:

答案 0 :(得分:2)

首先 - 确保你没有实施A +,除非你有充分的理由去做。实现良好的承诺是非常棘手的。

当promise未决时 - 将以下内容推送到处理程序数组:

  • 你要回来的承诺 - 因为Promises A +要求你检测一个承诺,然后拒绝回复。
  • 您从构造函数中提取的promise的拒绝函数。
  • 您从构造函数中提取的promise的resolve函数。
  • onFulfilled handler
  • onRejected处理程序。

当返回新承诺的承诺得到解决时,您需要

  • 如果它被拒绝 - 在完成后运行拒绝处理程序和resolve(如果它抛出则拒绝)。检查返回值的相同参考。如果没有处理程序或它不是函数 - 您可以改为e => { throw e; }
  • 如果满足 - 运行履行处理程序并resolve完成后(如果抛出则拒绝)。检查返回值的相同参考。如果没有处理程序或它不是函数 - 您可以改为v => v

当然,resolve本身需要进行同化,以及来自外国人的同化。我建议对Promises / A +测试套件进行运行并逐步解决,直到所有测试都通过。