我的前端进阶学习(二)—— promise

来源:互联网 发布:ubuntu怎么连接 编辑:程序博客网 时间:2024/06/06 18:22

随着技术的发展,我们在编写的前端程序越来越复杂,其中有一个就是对异步任务的处理。我们希望在处理异步调用时需要对两种结果进行操作——成功操作和失败处理。再成功调用后,我们还可能将返回的结果用在另一个异步任务中,这样就会出线“函数连环嵌套”的情况。可以看看下面的示例代码:

function getSometing(data, onload, onerror) {    var xhr, results, url;    url = 'url' + data;    xhr = new XMLHttpRequest();    xhr.open('GET', url, true);    xhr.onload = function () {        // 成功回调函数        if (this.status === 200) {            results = JSON.parse(this.responseText);            onload(results);        }    };    xhr.onerror = function (e) {        // 失败回调函数        onerror(e);    };    xhr.send();}function handleError(error) {}  // 错误处理函数function handleResult() {}      // 结果处理函数function doSomething() {    var container = document.getElementById('container');    searchTwitter('data1', function (result1) {        searchTwitter('data2', function (result2) {            handleResult(result1, result2);            });        }, handleError);    }, handleError);}

上面的代码是一段典型的处理Ajax的程序,我们可以看到有许多的嵌套的回调函数在其中。这样的代码即不容易理解,看起来也不太美观,同时对错误的处理也变得十分的分散。而我在 Ajax 的源码中,学习到了一种方法正好可以处理这样的问题,这种处理模式称为promise

promise的英文意思有承诺(诺言)的意思,用在这里我们可以简单的理解为:异步函数在处理的过程中返回了代表承诺的promise对象。我们通过在对象上进行操作来完成我们的后续操作。

下面是引用别人对promise的解释:

所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。

promise模式在任何时刻都处于以下三种状态之一:未完成(unfulfilled)、已完成(resolved)和拒绝(rejected)。以CommonJS Promise/A 标准为例,promise对象上的then方法负责添加针对已完成和拒绝状态下的处理函数。then方法会返回另一个promise对象,以便于形成promise管道,这种返回promise对象的方式能够支持开发人员把异步操作串联起来,如then(resolvedHandler, rejectedHandler); 。resolvedHandler 回调函数在promise对象进入完成状态时会触发,并传递结果;rejectedHandler函数会在拒绝状态下调用。

如何自己实现一个promise

我的目的不仅仅是简单了解promise,而是自己去实现一个promise

先看看 Ajax 是怎样做的。具体看下面代码的注释。
下面的代码不推荐新手看,真的不推荐

function Ajax(options) {    options = options || {}    // 定义对象保存相关内容,这一个值得学习    var $public = {}    var $private = {}    // 定义 promise 需要的几种方法    $private.methods = {        then: function () { },        catch: function () { },        always: function () { },    }    // $public.get() == function(){}      // 函数返回一个 Ajax 操作的结果    $public.get = function (url, data) {        // 注意这里,这个操作返回的就是我们一个 `promise` 对象        return $private.xhrConnection(method, url, data, options);    }    $private.xhrConnection = function xhrConnection(type, url, data, options) {        // 通过 readystatechange 事件改变 `promise` 的状态        xhr.addEventListener('readystatechange', $private.ready, false)        // 返回 $private.promises 返回值 ==> allPromises        return $private.promises()    }    $private.ready = function ready() {        var xhr = this        if (xhr.readyState === xhr.DONE) {            xhr.removeEventListener('readystatechange', $private.ready, false)            $private.methods.always                .apply($private.methods, $private.parseResponse(xhr))            if (xhr.status >= 200 && xhr.status < 300) {                // 成功处理函数                $private.methods.then                    .apply($private.methods, $private.parseResponse(xhr))            } else {                // 失败处理函数                $private.methods.catch                    .apply($private.methods, $private.parseResponse(xhr))            }        }    }    $private.promises = function promises() {        // 设置对应的回调函数        var allPromises = {}        Object.keys($private.methods).forEach(function (method) {            allPromises[method] = $private.generatePromise.call(this, method)        }, this)        return allPromises    }    $private.generatePromise = function generatePromise(method) {        return function (callback) {            $private.methods[method] = callback            return this        }    }    return $public}(<a href="http://www.dztcsd.com/">资质代办</a>)

自己实现的话可以参考下面的 《JavaScript异步编程的Promise模式》 文章,我这里没有合适的演示代码,以后有的话再补上。

总结

其实promise这个东西我很早前就接触过,但心中一直对不了解的东西有所抵触,导致自己一直都没有真正的去理解这些东西。

但如果一直因为不了解或者觉得这个东西很难,自己不想学的话,那么就永远没有机会去学习它。


作者: LLeo小浩 
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作!
0 0