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+规范

分类:  JavaScript




    本文转自 咖啡机(K.F.J)   博客园博客,原文链接:http://www.cnblogs.com/strick/p/5092092.html ,如需转载请自行联系原作者
相关文章
|
7月前
|
JavaScript 前端开发 测试技术
JavaScript的基本规范
JavaScript的基本规范
|
1月前
|
缓存 JavaScript 前端开发
掌握现代JavaScript异步编程:Promises、Async/Await与性能优化
本文深入探讨了现代JavaScript异步编程的核心概念,包括Promises和Async/Await的使用方法、最佳实践及其在性能优化中的应用,通过实例讲解了如何高效地进行异步操作,提高代码质量和应用性能。
|
4月前
|
JavaScript 前端开发 程序员
JS小白请看!一招让你的面试成功率大大提高——规范代码
JS小白请看!一招让你的面试成功率大大提高——规范代码
|
5月前
|
JavaScript 前端开发
node.js 导入导出模块(CommonJS模块化规范,ES6模块化规范)
node.js 导入导出模块(CommonJS模块化规范,ES6模块化规范)
68 1
|
6月前
|
JavaScript 前端开发
JavaScript的规范代码风格
JavaScript的规范代码风格
25 1
|
7月前
|
缓存 JavaScript 前端开发
前端 JS 经典:CommonJs 规范
前端 JS 经典:CommonJs 规范
67 0
|
7月前
|
前端开发 JavaScript 编译器
深入解析JavaScript中的异步编程:Promises与async/await的使用与原理
【4月更文挑战第22天】本文深入解析JavaScript异步编程,重点讨论Promises和async/await。Promises用于管理异步操作,有pending、fulfilled和rejected三种状态。通过.then()和.catch()处理结果,但可能导致回调地狱。async/await是ES2017的语法糖,使异步编程更直观,类似同步代码,通过事件循环和微任务队列实现。两者各有优势,适用于不同场景,能有效提升代码可读性和维护性。
|
7月前
|
JavaScript
JS模块化规范之ES6及UMD
JS模块化规范之ES6及UMD
92 3
|
JavaScript 前端开发
【Node学习】—Node.js中模块化开发的规范
【Node学习】—Node.js中模块化开发的规范
|
前端开发 JavaScript 编译器
前端开发规范:命名规范、html规范、css规范、js规范(四)
前端开发规范:命名规范、html规范、css规范、js规范
232 0