• JavaScript中Promises/A+规范的实现


    Promises是一种异步编程模型,通过一组API来规范化异步操作,这样也能够让异步操作的流程控制更加容易。

    下面的代码是假设执行一个异步队列,每一项都会使用上一项返回的数据:

    function nest(url, params, fn) {
        $.getJSON(url, params, function(data) {
            console.log(data);
            fn.call(this);
        });
    }
    nest('promise.php', {a:1}, function(data1) {
        nest('promise.php', {b:2}, function(data2) {
            nest('promise.php', {c:3}, function(data3) {
                console.log('同步完成');
            });
        });
    });

    这是一个回调金字塔,当异步的任务很多的时候,需要维护大量的callback。这嵌套的自己眼睛都看不清了吧。

    Promise/A+规范就是为了解决上面的问题,可以用类似下面的代码来改进,“nest”也会做些修改:

    promise.then(nest('promise.php', {a:1}))
        .then(nest('promise.php', {b:2}))
        .then(nest('promise.php', {c:3}));

    下图是改进的图片示例,我在画图的时候也感觉到,左边的比较难画,右边的很好画。

    接下来会围绕改进金字塔,实现规范展开。

    一、Promises/A+规范说明

    Promises/A+规范如下:

    1)一个promise可能有三种状态:等待(pending)、已完成(fulfilled)、已拒绝(rejected)

    2)一个promise的状态只可能从“等待”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换

    3)promise必须实现then方法,而且then必须返回一个promise

    4)同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致

    5)then方法接受两个参数,第一个参数是成功时的回调,在promise由“等待”态转换到“完成”态时调用

    6)另一个是失败时的回调,在promise由“等待”态转换到“拒绝”态时调用。

    7)then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。

    接下来先实现一个简易的,只有完成状态,没有拒绝和等待状态。

    二、简单实现

    Promise对象的实现:

    function Promise(fn) {
      this._status = 'pending';
      this._resolves = []; //队列
      this._fn = fn;
      return this;
    }
    Promise.prototype = {
      then: function(resolve) {
        var next = this._next || (this._next = new Promise()); //下一个promise对象
        this._resolves.push(resolve); //设置队列
        return next;
      },
      resolved: function(value) { //改变状态
        this._status = 'fulfilled';
        this._result = (this._fn && this._fn(value)) || value;
        while (fn = this._resolves.shift()) { //循环调用队列
          this._fire(this._next, fn);
        }
      },
      _fire: function(nextPromise, nextFn) {
        var nextResult = nextFn(this._result);
        if (nextResult instanceof Promise) { //判断回调是否是Promise对象
          //只有当nextResult的状态为fulfilled,下一个promise才可以执行
          nextResult.then(function(value) {
            nextPromise.resolved(value);
          });
        } else {
          nextPromise.resolved(nextResult);
        }
      }
    };

    演示用的函数:

    function nest2(url, params) {
      return function(pre) {
        var promise = new Promise();
        $.getJSON(url, params, function(data) {
          promise.resolved(data);
        });
        return promise;
      };
    }
    
    function begin(value) {
      return value + '!';
    }

    初始化代码:

    var promise = new Promise(begin);
    promise.then(nest2('promise.php', {a: 1}))
      .then(nest2('promise.php', {b: 2}));
    promise.resolved('开始');

    也可以另外一种方式调用,这样的话内部的_resloves队列中会有多个值

    var promise = new Promise(begin);
    promise.then(nest2('promise.php', {a: 1})) promise.then(nest2('promise.php', {b: 2})); promise.resolved('开始');

    demo下载:

    http://download.csdn.net/detail/loneleaf1/9391315

    参考资料:

    http://www.alloyteam.com/2014/05/javascript-promise-mode/   JavaScript Promise启示录

    http://www.cnblogs.com/fsjohnhuang/p/4135149.html   JS魔法堂:剖析源码理解Promises/A规范

    http://www.cnblogs.com/aaronjs/archive/2012/11/17/2774440.html   使用Promises/A

    http://rapheal.sinaapp.com/2013/01/26/jquery-src-deferred/   $.Deferred

    http://www.ituring.com.cn/article/66566   Promises/A+规范

  • 相关阅读:
    Autofac +webapi 配置
    net 记录controller Action耗时
    C# ASP.NET Core使用HttpClient的同步和异步请求
    C#实体对象序列化成Json,格式化,并让字段的首字母小写
    Razor 将C#对象转换成Javascript对象, json还原被转码的字符 &quot·· HTML转义符
    js 递归树结构数据查找父级
    api下载文件
    Ubuntu django+nginx 搭建python web服务器文件日志
    python scrapy cookies 处理
    ubuntu 环境下pycharm的 安装与激活教程 以及错误解决方法
  • 原文地址:https://www.cnblogs.com/strick/p/5092092.html
Copyright © 2020-2023  润新知