当前位置: 首页 > 知识库问答 >
问题:

概念——蒸馏promise是如何工作的?

司寇星海
2023-03-14

我看过很多实现,它们看起来都很不一样,我真的无法提炼promise的本质。

如果我不得不猜测它只是一个函数,当回调触发时运行。

有人能在几行代码中实现最基本的promise吗。

例如,从这个答案

片段1

var a1 = getPromiseForAjaxResult(ressource1url);
a1.then(function(res) {
    append(res);
    return a2;
});

传递给的函数如何知道何时运行。

也就是说,它是如何传递回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){
        // ??
    };
    // ??
}())

共有3个答案

夔桐
2023-03-14

我已经在ES7中实现了一个。如果算上少的话,使用链式链接的话,它是70行。我认为状态机是实现promise的正确范例。生成的代码比许多ifs IMHO更容易理解。本文对此进行了详细描述。

代码如下:

const states = {
    pending: 'Pending',
    resolved: 'Resolved',
    rejected: 'Rejected'
};

class Nancy {
    constructor(executor) {
        const tryCall = callback => Nancy.try(() => callback(this.value));
        const laterCalls = [];
        const callLater = getMember => callback => new Nancy(resolve => laterCalls.push(() => resolve(getMember()(callback))));
        const members = {
            [states.resolved]: {
                state: states.resolved,
                then: tryCall,
                catch: _ => this
            },
            [states.rejected]: {
                state: states.rejected,
                then: _ => this,
                catch: tryCall
            },
            [states.pending]: {
                state: states.pending,
                then: callLater(() => this.then),
                catch: callLater(() => this.catch)
            }
        };
        const changeState = state => Object.assign(this, members[state]);
        const apply = (value, state) => {
            if (this.state === states.pending) {
                this.value = value;
                changeState(state);
                for (const laterCall of laterCalls) {
                    laterCall();
                }
            }
        };

        const getCallback = state => value => {
            if (value instanceof Nancy && state === states.resolved) {
                value.then(value => apply(value, states.resolved));
                value.catch(value => apply(value, states.rejected));
            } else {
                apply(value, state);
            }
        };

        const resolve = getCallback(states.resolved);
        const reject = getCallback(states.rejected);
        changeState(states.pending);
        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error);
        }
    }

    static resolve(value) {
        return new Nancy(resolve => resolve(value));
    }

    static reject(value) {
        return new Nancy((_, reject) => reject(value));
    }

    static try(callback) {
        return new Nancy(resolve => resolve(callback()));
    }
}
白光耀
2023-03-14

最基本的promise,有人能做到几行字吗?

这是:

function Promise(exec) {
    // takes a function as an argument that gets the fullfiller
    var callbacks = [], result;
    exec(function fulfill() {
        if (result) return;
        result = arguments;
        for (let c;c=callbacks.shift();)
            c.apply(null, arguments);
    });
    this.addCallback = function(c) {
        if (result)
            c.apply(null, result)
        else
            callbacks.push(c);
    }
}

附加然后与链接(您将需要答案):

Promise.prototype.then = function(fn) {
    return new Promise(fulfill => {
        this.addCallback((...args) => {
            const result = fn(...args);
            if (result instanceof Promise)
                result.addCallback(fulfill);
            else
                fulfill(result);
        });
    });
};

这两个片段有何关联?

ajax是从getPromiseForAjaxResult函数调用的:

function getPromiseForAjaxResult(ressource) {
    return new Promise(function(callback) {
        ajax({url:ressource}, callback);
    });
}
邹桐
2023-03-14
匿名用户

从根本上说,promise只是一个对象,它有一个标志,表明它是否已经解决,以及它维护的函数列表,以通知它是否/何时解决。代码有时可以说更多的话,所以这里有一个非常基本的非真实世界的例子,纯粹是为了帮助交流概念而缩进的:

// 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对象本身之外的(当然,这取决于实际使用,您可以将它们组合起来

同样,上述内容纯粹是概念性的,缺少了在任何实际的promise实现中必须具备的几个重要方面,以使其发挥作用:

>

  • 然后解决应该总是异步调用回调,即使promise已经解决。然后应该,因为否则调用者不知道回调是否是异步的。 返回了之后。(es2015的promise做到了这两件事。jquery的 Deferred没有。) 返回了之后。(es2015的promise做到了这两件事。jquery的

    然后结算应确保回调失败(例如异常)不会直接传播到调用然后结算的代码。这部分与上面的#1有关,更与下面的#3有关。

    then应根据调用回调的结果(then或更高版本)返回新的promise。这对于组合操作来说是相当基本的,但会使上述操作变得非常复杂。任何合理的promise都会实现。

    我们需要不同类型的“解决”操作:“解决”(底层操作成功)和“拒绝”(失败)。一些用例可能有更多的状态,但解决和拒绝是基本的两个。(ES2015的promise有决心也有拒绝。)

    我们可能会以某种方式将结算(或单独的结算拒绝)保密,以便只有promise的创造者才能结算。(ES2015)promise

    等等等等。

  •  类似资料:
    • 是否有在java中使用Promise(就像在JavaScript中使用ut一样)而不是使用嵌套回调的概念? 如果是这样,是否有一个在java中实现回调和链接处理程序的示例?

    • 问题内容: “类(及其子类)的每个实例都具有一个锁,该锁在方法进入时获得,并在退出时自动释放” 这是否意味着我们创建的任何对象实例默认情况下内部都具有“锁”(实现为字段)? 我对这个“锁”概念感到困惑,我想知道它实际上在内部做什么。 有人可以将我引导到一些我可以找到更多信息的地方吗? 问题答案: 与往常一样,JLS提供了答案(17.1): 这些方法中最基本的是同步,它是使用监视器实现的。Java中

    • 函数在 Rust 代码中应用广泛。你已经见过一个语言中最重要的函数: 函数,它是很多程序的入口点。你也见过了 fn 关键字,它用来声明新函数。 Rust 代码使用 snake case 作为函数和变量名称的规范风格。在 snake case 中,所有字母都是小写并使用下划线分隔单词。这里是一个包含函数定义的程序的例子: 文件名: src/main.rs Rust 中的函数定义以 fn 开始并在函数

    • 我正在努力弄清楚我是否正确理解负载平衡。我有一个用XAMPP开发的web应用程序。基本上我有一个数据库和应用程序本身。之后,我在运行Ubuntu的VPS中的Digital Ocean中托管了该应用程序,并在其中安装了ApacheMySQL和PHP。现在我想了解负载平衡的要求。 从我到目前为止所读到的关于负载平衡的内容来看,您至少需要3台服务器,其中一台将是Apache或NGINX,并打开相应的负载

    • 问题内容: 我看过许多实现,它们看起来都如此不同,以至于我无法真正提炼出诺言的实质。 如果我不得不猜测,它只是在触发回调时运行的函数。 有人可以在不带链接的几行代码中实现最基本的承诺。 片段1 该函数如何传递才能知道何时运行。 也就是说,它如何传递回ajax完成时触发的回调代码。 片段2 这两个摘要有什么关系? 猜测: 问题答案: 有人可以在几行中实现最基本的承诺吗? 这里是: 这两个摘要有什么关

    • “cadence有‘工作流进化’的概念吗? 换句话说,我有一个为客户建模的“有状态参与者”。最初,客户有两个字段,其中包含一些修改它们的信号方法、一些获取状态的查询方法以及该参与者的一些主要工作流。假设我有10个这样的实例,它们是长期存在的。 稍后我想添加第三个字段,也许是另一个信号方法。我能用什么?