原文地址:http://www.cnblogs.com/dojo-lzz/p/4340897.html

解决回调函数嵌套太深,并行逻辑必须串行执行,一个Promise代表一个异步操作的最终结果,跟Promise交互的主要方式是通过他的then()方法来注册回调函数,去接收Promise的最终结果值

Promise相关的协议有PromiseA和PromiseA+

定义一个类Promise

定义属性队列queue,初始化空数组[]

定义属性值value,初始化null

定义属性状态status,初始化“pending”(默认值)

定义成员方法getQueue(),返回属性queue

定义成员方法getStatus(),返回属性status

定义成员方法setStatus(),设置状态,传递参数:status,value

判断status为fulfilled或者rejected,

设置status属性this.status=status

设置value属性this.value=value || null ,如果不传value就是null

定义冻结变量freezeObject

定义成员方法isFulfilled(),判断当前状态是否是(完成)

定义成员方法isRejected(),判断当前状态是否是(失败)

定义成员方法isPending(),判断当前状态师傅是(等待)

定义成员方法then(),传递参数:onFulfilled成功的回调,onRejected失败的回调

定义对象handler对象,属性fulfilled,rejected两个回调函数

定义handler对象的deferred属性,Deferred对象

判断当前状态是否等待,如果是等待 把handler对象塞入queue队列数组

如果不是等待状态,调用Utils对象的procedure()方法,参数:status,

返回 handler.deferred.promise对象

定义一个类Deferred

定义属性promise,初始化Promise对象

定义成员方法resolve(),传递参数:result结果

判断Promise对象的状态是 等待,直接返回

调用Promise对象的getQueue()方法,获取queue数组

循环数组

//todo调用工具类Utils. procedure()方法,参数:“fulfilled”,元素,err信息

调用Promise对象的setStatus()方法,设置状态,参数:'fulfilled',result

定义成员方法reject,传递参数:err错误信息

判断Promise对象的状态是 等待,直接返回

调用Promise对象的getQueue()方法,获取queue数组

循环数组

//todo,调用工具类Utils. procedure()方法,参数:“rejected”,元素,err信息

调用Promise对象的setStatus()方法,设置状态,参数:'fulfilled',result

定义工具类Utils,使用匿名函数立即执行,得到一个对象

返回对象,对象中有一个方法procedure()

定义procedure()方法,传递参数:type状态类型,handler处理器数组,result结果

获取到处理函数func,在handler[type]

到这里我看晕了。。。

使用方法:

定义一个函数ajax,传递参数:url路径

获取Deferred对象,new出来

ajax请求数据的代码,在返回数据的回调方法中

如果成功了调用Deferred对象的resolve()方法,参数:返回的数据

如果失败了调用Deferred对象的reject()方法,参数:返回的数据

返回Deferred.promise对象

调用ajax()方法,得到promise对象,参数:url,

调用promise对象的then()方法,参数:匿名函数

调用ajax()方法,获取到promise对象,返回这个对象

形成链式调用

js部分:

<script>
//Promise代码部分(我选择狗带)
Promise = function() {
this.queue = [];
this.value = null;
this.status = 'pending';// pending fulfilled rejected
}; Promise.prototype.getQueue = function() {
return this.queue;
};
Promise.prototype.getStatus = function() {
return this.status;
};
Promise.prototype.setStatus = function(s, value) {
if (s === 'fulfilled' || s === 'rejected') {
this.status = s;
this.value = value || null;
this.queue = [];
var freezeObject = Object.freeze || function(){};
freezeObject(this);// promise的状态是不可逆的
} else {
throw new Error({
message: "doesn't support status: " + s
});
}
};
Promise.prototype.isFulfilled = function() {
return this.status === 'fulfilled';
};
Promise.prototype.isRejected = function() {
return this.status === 'rejected';
}
Promise.prototype.isPending = function() {
return this.status === 'pending';
}
Promise.prototype.then = function(onFulfilled, onRejected) {
var handler = {
'fulfilled': onFulfilled,
'rejected': onRejected
};
handler.deferred = new Deferred(); if (!this.isPending()) {//这里允许先改变promise状态后添加回调
utils.procedure(this.status, handler, this.value);
} else {
this.queue.push(handler);//then may be called multiple times on the same promise;规范2.2.6
}
return handler.deferred.promise;//then must return a promise;规范2.2.7
}; var utils = (function(){
var makeSignaler = function(deferred, type) {
return function(result) {
transition(deferred, type, result);
}
}; var procedure = function(type, handler, result) {
var func = handler[type];
var def = handler.deferred; if (func) {
try {
var newResult = func(result);
if (newResult && typeof newResult.then === 'function') {//thenable
// 此种写法存在闭包容易造成内存泄露,我们通过高阶函数解决
// newResult.then(function(data) {
// def.resolve(data);
// }, function(err) {
// def.reject(err);
// });
//PromiseA+规范,x代表newResult,promise代表def.promise
//If x is a promise, adopt its state [3.4]:
//If x is pending, promise must remain pending until x is fulfilled or rejected.
//If/when x is fulfilled, fulfill promise with the same value.
//If/when x is rejected, reject promise with the same reason.
newResult.then(makeSignaler(def, 'fulfilled'), makeSignaler(def, 'rejected'));//此处的本质是利用了异步闭包
} else {
transition(def, type, newResult);
}
} catch(err) {
transition(def, 'rejected', err);
}
} else {
transition(def, type, result);
}
}; var transition = function(deferred, type, result) {
if (type === 'fulfilled') {
deferred.resolve(result);
} else if (type === 'rejected') {
deferred.reject(result);
} else if (type !== 'pending') {
throw new Error({
'message': "doesn't support type: " + type
});
}
}; return {
'procedure': procedure
}
})(); Deferred = function() {
this.promise = new Promise();
}; Deferred.prototype.resolve = function(result) {
if (!this.promise.isPending()) {
return;
} var queue = this.promise.getQueue();
for (var i = 0, len = queue.length; i < len; i++) {
utils.procedure('fulfilled', queue[i], result);
}
this.promise.setStatus('fulfilled', result);
}; Deferred.prototype.reject = function(err) {
if (!this.promise.isPending()) {
return;
} var queue = this.promise.getQueue();
for (var i = 0, len = queue.length; i < len; i++) {
utils.procedure('rejected', queue[i], err);
}
this.promise.setStatus('rejected', err);
}
/*****************************上面看不懂,分割线************************************/
//测试部分
ajax = function(url) {
var def = new Deferred(); var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if ((xhr.status >=200 && xhr.status < 300) || xhr.status === 304) {
def.resolve(xhr.responseText)
} else {//简化ajax,没有提供错误回调
def.reject(new Error({
message: xhr.status
}));
}
}
};
xhr.open('get', url, true);
xhr.send(null); return def.promise;
} ajax('test.php?act=1').then(function(data1) {
console.log(data1);//处理data1
return ajax('test.php?act=2');
}).then(function(data2) {
console.log(data2);//处理data2
return ajax('test.php?act=3');
}, function(err) {
console.error(err);
}).then(function(data3) {
console.log(data3);
alert('success');
}, function(err) {
console.error(err);
});
</script>

php:

<?php
if($_GET['act']==1){
echo json_encode(array("code"=>200));
}else if($_GET['act']==2){
echo json_encode(array("code"=>300));
}else if($_GET['act']==3){
echo json_encode(array("code"=>400));
}

[javascript] Promise简单学习使用的更多相关文章

  1. django之JavaScript的简单学习2

    前言:ajax预备知识:json进阶 1.JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.JSON是用字符串来表示Javascript对象: 请大家记住一 ...

  2. JavaScript 的简单学习2

    AJAX 一 AJAX预备知识:json进阶 1.1 什么是JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.JSON是用字符串来表示Javas ...

  3. JavaScript闭包简单学习

    因为实验室项目要用,所以最近在学习OpenLayers,但是从来没有做过前端呀,坑爹的,硬着头皮上吧 反正正好借这个机会学习一下JS,本来对这门语言也挺感兴趣的,多多少少写过一下JS代码了,差不多学一 ...

  4. javaScript的简单学习

    JavaScript介绍 JavaScript跟java没半毛钱关系 JavaScript有三部分组成:ECMAScript,document object model,broswer object ...

  5. Javascript Promise对象学习

    ES6中的Promise对象 var p = new Promise(function(resolve, reject){ window.setTimeout(function(){ console. ...

  6. JavaScript Promise的学习笔记

    首先声明:本人今天刚接触Promise,通过一个例子,希望能更好的来理解,如果有不对的地方,还望指正 Promise是专门为解决 js中回调而引起的各种问题,而产生的. 在异步编程中,我们经常使用回调 ...

  7. JavaScript 标准内置对象Promise使用学习总结

    Javascript标准内置对象Promise使用学习总结   by:授客 QQ:1033553122 1.   基础用法 var condition = true; let p = new Prom ...

  8. Javascript Promise 学习(上)

    Promise 就是处理异步的一个规范方法 a();b();alert("a");如果a() 里面有一个ajax 或者settimeout 那么alert("a" ...

  9. Javascript Promise 学习笔记

    1.     定义:Promise是抽象异步处理对象以及对其进行各种操作的组件,它把异步处理对象和异步处理规则采用统一的接口进行规范化. 2.     ES6 Promises 标准中定义的API: ...

随机推荐

  1. Day 34 面试题

  2. 标准 OpenStack 多region配置

    首先搭建两套一样的OpenStack环境 更改前: node1: 192.168.200.100 RegionOne node2: 192.168.200.200 RegionOne 预期结果: no ...

  3. 768. Max Chunks To Make Sorted II

    This question is the same as "Max Chunks to Make Sorted" except the integers of the given ...

  4. HDU 6198(2017 ACM/ICPC Asia Regional Shenyang Online)

    思路:找规律发现这个数是斐波那契第2*k+3项-1,数据较大矩阵快速幂搞定.   快速幂入门第一题QAQ #include <stdio.h> #include <stdlib.h& ...

  5. kali Linux 上编译并使用RFID核弹——proxmark3

    你还在在Windows下使用proxmark3?弱爆了! 本文作者:i春秋签约作家——冰尘 作为一个标准的日天日地日空气的(单身贵族泰迪)物理黑客Proxmark3这么高大上的东西应该是在键盘敲打声中 ...

  6. 移动端 实现ul横向滚动条

    ul { display: flex; width: 100%; height: 3.333333rem; background: #fff; padding: 0.373333rem 0.32rem ...

  7. js实现仿华为手机计算器,兼容电脑和手机屏幕

    效果图: 电脑端: 手机端: 源码: <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  8. java语言学习指南

    1 java基础 1.1 java语言编程入门 1.2 java语言概述 1.3 java基本语法一 1.4 java基本语法二 1.5 java基本语法三

  9. HUE配置文件hue.ini 的yarn_clusters模块详解(图文详解)(分HA集群和非HA集群)

    不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...

  10. ms-sql 给表列添加注释

    需求: 在创建数据库是对相应的数据库.表.字段给出注释. 解决方案: 首先,要明确一点的是注释存在sysproperties表中而不是跟创建的表捆绑到一起的(我的理解). 一.使用SQL Server ...