本篇文章主要介绍了异步编程promise模式的简单实现,并对每一步进行了分析,需要的朋友可以参考下

异步编程
javascript异步编程,
web2.0时代比较热门的编程方式,我们平时码的时候也或多或少用到,最典型的就是异步ajax,发送异步请求,绑定回调函数,请求响应之后调用指定的
回调函数,没有阻塞其他代码的执行。还有像setTimeout方法同样也是异步执行回调的方法。

如果对异步编程还不太熟悉的话,直接戳 阮一峰大牛的教程 ,这篇文章介绍了四种异步编程的方式:

  1. 回调函数
  2. 事件监听
  3. 发布/订阅
  4. promise模式

这几种方式的可维护性逐级递增,理解难度也逐级递增。这篇总结也是针对promise模式的。

promise模式
那么多中异步编程的方式,为什么选择promise, 因为前面几种方式不够灵活,用起来不够痛快,不优雅。为了降低异步编程的复杂性,所以promise。

promise的核心是有一个promise对象,这个对象有一个重要的then()方法, 它用于指定回调函数,如:

f1().then(f2);

promise模式在任何时刻都有三种状态:已完成(resolved),未完成(unfulfilled),那么then()方法就是为状态变化指定不同的回调函数,并总是返回一个promise对象,方便链式调用。

那promise模式下,返回的数据如何在各个回调函数之间传播呢,通过resolve方法,你可以将一个函数的返回值作为参数传递给另一个函数,并且将另一个函数的返回值作为参数再传递给下一个函数……像一条“链”一样无限的这么做下去。

代码实现
通过创建一个Promise构造函数来实现promise模式:

//constructor
var Promise = function() {
this.callbacks = [];
}
Promise.prototype = {
construct: Promise,
resolve: function(result) {
this.complete("resolve", result);
},
reject: function(result) {
this.complete("reject", result);
},
complete: function(type, result) {
while (this.callbacks[0]) {
this.callbacks.shift()[type](result);
}
},
then: function(successHandler, failedHandler) {
this.callbacks.push({
resolve: successHandler,
reject: failedHandler
});
return this;
}
}
// test
var promise = new Promise();
var delay1 = function() {
setTimeout(function() {
promise.resolve('数据1');
}, 1000);
return promise;
};
var callback1 = function(re) {
re = re + '数据2';
console.log(re);
};
delay1().then(callback1)

  

代码分析
我们可看到一个简单的promise对象的构造函数的结构:

  • callbacks: 用于管理回调函数
  • resolve: 请求成功时执行的方法
  • reject:请求失败时执行的方法
  • complete: 执行回调
  • then:绑定回调函数

测试:

var promise = new Promise();
var delay1 = function() {
setTimeout(function() {
promise.resolve('数据1');
}, 1000);
return promise;
};
var callback1 = function(re) {
re = re + '数据2';
console.log(re);
promise.resolve(re);
};
var callback2 = function(re) {
console.log(re + '数据3');
};
delay1().then(callback1).then(callback2);

结果:

一秒之后输出:

分析:

//第一步
var delay1 = function() {
setTimeout(function() {
promise.resolve('数据1');
}, 1000);
return promise;
};

这个函数通过setTimeout方法,异步传递一个数据1,并返回一个promise对象(必须)。

//第二步
var callback1 = function(re) { re = re + '数据2';
console.log(re);
promise.resolve(re);
};

callback1和callback2都是要通过then方法注册的回调函数,其中callback1通过resolve方法把数据往下传递。

//第三步
delay1().then(callback1).then(callback2);

  

delay1()方法执行完,因为返回了一个promise对象,所以可以再调用then()方法为delay1()的setTimeout异步执行操作指定回调函数, 又因为then()方法也返回的是promise对象,所以还可以再调用then方法

//第四步
setTimeout(function() {
promise.resolve('数据1');
}, 1000);

一秒之后,当其他代码执行完成,开始执行异步代码promise.resolve('数据1');,这里调用promise的resolve()方法,指定了一个成功状态,并把数据1作为参数。

//第五步
resolve: function(result) {
this.complete("resolve", result);
},
//第六步:循环执行回调,将上一个回调的结果传递给下一个回调
complete: function(type, result) {
while (this.callbacks[0]) {
this.callbacks.shift()[type](result);
}
},

这其中比较难理解的就是第五,六步。

以上就是本文的全部内容,希望对大家的学习有所帮助。

转自(http://www.jb51.net/article/70447.htm)

简单实现异步编程promise模式的更多相关文章

  1. 异步编程——promise

    异步编程--promise 定义 Promise是异步编程的一个解决方案,相比传统的解决方法--回调函数,使用Promise更为合理和强大,避免了回调函数之间的层层嵌套,也使得代码结构更为清晰,便于维 ...

  2. 异步编程Promise/Deferred、多线程WebWorker

    长期以来JS都是以单线程的模式运行的,而JS又通常应用在操作用户界面和网络请求这些任务上.操作用户界面时不能进行耗时较长的操作否则会导致界面卡死,而网络请求和动画等就是耗时较长的操作.所以在JS中经常 ...

  3. 简述异步编程&Promise&异步函数

    前言:文章由本人在学习之余总结巩固思路,不足之前还请指出. 一.异步编程 首先我们先简单来回顾一下同步API和异步API的概念 1.同步API:只有当前的API执行完成之前,才会执行下一个API 例: ...

  4. 异步编程promise

    异步编程发展 异步编程经历了 callback.promise.async/await.generator四个阶段,其中promise和async/await使用最为频繁,而generator因为语法 ...

  5. AnjularJS异步编程 Promise和$q

    Promise,是一种异步处理模式. js代码的函数嵌套会使得程序执行异步代码时很难调试.因为多重嵌套的函数无法确定何时触发回调. 如: funA(arg1,arg2,function(){ func ...

  6. es6异步编程 Promise 讲解 --------各个优点缺点总结

    //引入模块 let fs=require('fs'); //异步读文件方法,但是同步执行 function read(url) { //new Promise 需要传入一个executor 执行器 ...

  7. 你所必须掌握的三种异步编程方法callbacks,listeners,promise

    目录: 前言 Callbacks Listeners Promise 前言 coder都知道,javascript语言运行环境是单线程的,这意味着任何两行代码都不能同时运行.多任务同时进行时,实质上形 ...

  8. C#异步编程之基于任务的异步模式

    http://www.cnblogs.com/afei-24/p/6757361.html该文讲了基于任务的编程,这里再详细介绍一下.一.延续任务 private async static void ...

  9. JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上

    众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...

随机推荐

  1. android 入门-控件 测量状态栏高度

    private ViewTreeObserver viewTreeObserver; /** 获取可見区域高度 **/ WindowManager manager = getWindowManager ...

  2. [Linux] 安装JDK和Maven及hadoop相关环境

    紧接上一篇,继续安装hadoop相关环境 JDK安装:     1. 下载,下面这两个地址在网上找的,可以直接下载:         http://download.oracle.com/otn-pu ...

  3. 10g ASM下修改control file的位置

    1.查看位置以及name是否正确 SQL> sho parameter name NAME TYPE VALUE ------------------------------------ --- ...

  4. zzy:请求静态资源和请求动态资源, src再次请求服务器资源

    [总结可以发起请求的阶段:请求动态资源:通过web.xml匹配action然后,自定义Servlet处理该action1)form表单提交请求的时候,用action设定,该页面发起请求的Servlet ...

  5. linux网络协议

    网络协议 本章节主要介绍linxu网络模型.以及常用的网络协议分析以太网协议.IP协议.TCP协议.UDP协议 一.网络模型 TCP/IP分层模型的四个协议层分别完成以下的功能: 第一层 网络接口层 ...

  6. 用PowerShell脚本实现对SharePoint页面Title的修改

    存在这样一种情况,对应的page已经部署到product的SharePoint环境中,那么在部署下一个版本的时候就不允许把已经创建好的page删除再创建,因此page中修改过的属性就不能再次部署到Sh ...

  7. user_jj两条记录改成一条

    1.前台index控制器,用user_jj.*add找到,home_ddxx_pcz_cl() 2.前台index控制器,用user_jj.*add找到,tgbz_list_sd_cl(),tgbz_ ...

  8. [工作中的设计模式]原型模式prototype

    一.模式解析 提起prototype,最近看多了js相关的内容,第一印象首先是js的原型 var Person=function(name){ this.name=name; } Person.pro ...

  9. js-高级技术

    高级技术: 1.function Person(name,age,job){ this.name=name; this.age=age; this.job=job; } var person=new ...

  10. ccpc_南阳 C The Battle of chibi dp + 树状数组

    题意:给你一个n个数的序列,要求从中找出含m个数的严格递增子序列,求能找出多少种不同的方案 dp[i][j]表示以第i个数结尾,形成的严格递增子序列长度为j的方案数 那么最终的答案应该就是sigma( ...