您的位置:首页 > Web前端 > JavaScript

Promise处理JS异步的问题

2015-02-12 17:01 537 查看
promise是一款轻量级的JS插件,我们可以利用它来处理JS中的一些异步的问题。我们可以去github上面下载最新的源码。链接地址:https://github.com/stackp/promisejs

注:咱们做前端或移动hybrid开发的,首先电脑上应该要装有node.一些调试的类对我们还是会有帮助的,比如console类。

首先我们来看一个简单的例子:

按顺序输出一些句子,之前的写法是这样子的:

function fn1(){
console.info("this is 1") ;
}
function fn2(){
console.info("this is 2");
}
function fn3(){
console.info("this is 3") ;
}
//按照顺序调用
fn1() ;
fn2() ;
fn3() ;
//输出的结果:
//this is 1
//this is 2
//this is 3


其实这样这做并不能保证fn1、fn2、fn3按照顺序的去执行的。大家都知道,javascritp是单线程执行的,假如fn2的方法里面涉及到了其他的回调函数,有可能程序在执行到fn2的时候会被挂起,而先去执行fn3。那么这样就不能按照我么期望的那样按照顺序去输出了。

现在我们是使用promise去帮我们解决这个问题:

<!DOCTYPE html>
<html>
<head>
<title>Promise Test</title>
<meta http-equiv="ContentType" content="text/html" charset="utf-8">
</head>
<body>
</boy>
<script type="text/javascript" src="promise.js"></script>
<script type="text/javascript">
function fn1(){
var p = new promise.Promise() ;
setTimeout(function(){
console.info("this is 1") ;
p.done() ;
},2000);
return p ;
}
function fn2(){
var p = new promise.Promise() ;
console.info("this is 2") ;
p.done() ;
return p ;
}
function fn3(){
var p = new promise.Promise() ;
console.info("this is 3") ;
p.done() ;
return p ;
}
fn1().then(fn2).then(fn3) ;
//输出的结果是:
//this is 1
//this is 2
//this is 3
</script>
</htlm>


前面也说过,javascript是单线程的,fn1中使用setTimeout的方法,fn1中的代码应该是延迟2秒钟后才去执行的。按理来说是程序会先把setTimeout中的代码挂起的,然后去执行fn2中的代码,但是输出的结果并不是样子的,还是按照fn1->fn2->fn3的顺序去执行的。这就是promise来处理的。

我们可以换下顺序调用 :fn3().then(fn1).then(fn3) ;

输出的结果:

//this is 3
//this is 1
//this is 2


代码解析:

要想了解为什么有这样的结果,咱们还是直接看一下源码:

function Promise() {
this._callbacks = [];
}

Promise.prototype.then = function(func, context) {
var p;
if (this._isdone) {
p = func.apply(context, this.result);
} else {
p = new Promise();
this._callbacks.push(function () {
var res = func.apply(context, arguments);
if (res && typeof res.then === 'function')
res.then(p.done, p);
});
}
return p;
};

Promise.prototype.done = function() {
this.result = arguments;
this._isdone = true;
for (var i = 0; i < this._callbacks.length; i++) {
this._callbacks[i].apply(null, arguments);
}
this._callbacks = [];
};


fn1().then(fn2).then(fn3) ; 毋庸置疑,该调用方式是从左往右调用的。首先咱们看下fn1执行的代码 :

setTimeout的里面的代码是验证2秒执行的,但是还是会执行 return p ;这句代码,接着调用then(fn2),我们看下源码中的then的方法:因为fn1此时还没有执行done()的方法,所以会_isdone是为”undefined”的,所以此时会执行else{ }里面的语句。下班了,该内容待续~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: