Reactive Extensions for JavaScript
的缩写。英文水平好的人可以翻译出来rxjs的中文意思是**JavaScript的响应式扩展 **,那什么是"响应式"?一个人看你不顺眼打了你一下,你立马回应(响应)他两个字"滚蛋",像这种你有变化,其他东西会立马跟着响应的方式就叫做"响应式"。Observables
是个什么东西在下面再讲,咱们先看看后半句说的它能使异步和回调编写的更容易,也就是说他里面肯定有比之前咱们用到的异步和回调方式好的地方对不对,那下面咱们先温故下异步和回调。 foo();
bar();
程序运行一般是同步的(synchronous),在上述例子中,如果bar 方法在 foo 方法执行完之后,再执行,这就是同步;如果先执行 foo 方法,foo 方法没执行完,就开始执行 bar 方法,这就成了异步。
我们都知道 JS 是一个单线程的语言,永远只有一个通道在运行程序。那么既然它是个单线程又如何会有异步呢?咱们先看看一下代码:
var foo = function () {
console.log('foo begins');
setTimeout(function () {
console.log('foo finishes');
}, 1000);
};
var bar = function () {
console.log('bar executed');
}
foo();
bar();
先想想会输出什么样的结果,再看答案,输出结果如下:
在这种情况下,foo finishes
并没有按顺序输出来,而是等bar()方法里的bar executed
输出来之后才输出,这样就形成了异步情况。
按照js的单线程规则,上述实例本来应该是想按顺序输出:foo begins
foo finishes
bar executed
,却不如人意。
再看下面一段代码:
var foo = function () {
console.log('foo begins');
setTimeout(function () {
console.log('foo finishes');
}, 1000);
};
var bar = function () {
var i = 6;
while (i > 5) {
console.log('bar executed');
}
}
foo();
bar();
想想这段代码会出现什么情况?
bar函数遇到死循环 foo finishes
输出不出来,这就很尴尬了。带着异步的这些缺点咱们再看看回调
看看这段代码:
var foo = function (callback) {
callback();
};
var bar = function () {
console.log('bar executed');
};
foo(bar);
其中,bar 就是一个回调函数。具体说是 bar 是 foo 的回调函数。
咱们看这段代码:
var foo = function (callback) {
console.log('foo begins');
setTimeout(function () {
console.log('foo finishes');
callback();
}, 1000);
};
var bar = function () {
console.log('bar executed');
}
foo(bar);
输出结果如下:
定睛一看,foo begins
foo finishes
bar executed
按顺序输出来了,这样是不是就解决了异步不按顺序输出的缺点了。接着咱们再看看这段代码:
var foo = function (callback) {
console.log('foo begins');
setTimeout(function () {
console.log('foo finishes');
callback();
}, 1000);
};
var bar = function () {
var i = 6;
while (i > 5) {
console.log('bar executed');
}
}
foo(bar);
输出结果如下:
foo finishes
并没有因为bar函数的死循环而输不出来,这样异步的上述缺点都可以用这种方式来解决了,像这种带有异步的回调方法统称为 异步回调。
想像一下,如果我们所传递的回调函数也是一个异步操作,也需要传入一个回调函数来处理异步结果怎么办?咱们就应该会这样写出来:
var foo = function (callback) {
console.log('foo begins');
setTimeout(function () {
console.log('foo finishes');
callback(co);
}, 1000);
};
var bar = function (callback) {
console.log('bar begins');
setTimeout(function () {
console.log('bar finishes');
callback();
}, 1000);
}
var co = function (callback) {
console.log('co executed');
}
foo(bar);
输出:
像这样一层套一层,使代码晦涩难懂、很不优雅。对于异步回调这种一层层嵌套的现象网上起了个名字叫回调地狱。于是下面就诞生了Promise。
咱先看看promise的写法:
function foo() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('foo begins');
resolve('foo finishes');
}, 2000);
});
}
function bar() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('bar begins');
resolve('bar finishes');
}, 2000);
});
}
function co() {
return new Promise(function (resolve, reject) {
console.log('co executed');
});
}
foo().then(function (data) {
console.log(data);
return bar();
}).then(function (data) {
console.log(data);
return co();
}).then(function (data) {
console.log(data);
});
输出:
其中,resolve(value)是在Promise在已经异步完成成功(Resolved)之后执行的
reject(value)是在Promise在异步失败之后(Rejected)执行。
当然,也可以用then来指定:then(resolve,reject)
或者:then(resolve),catch(reject)
这样promise很好的将异步回调的这种嵌套式调用转变成了链式调用,使得代码的可读性、维护性提高。
一旦调用了resolve或者reject之后便返回了,不能再次调用resolve或者reject,想象一下,若是从端口源源不断地发来消息,每次收到消息就要通知回调函数来处理,该怎么办呢?
1、程序员分类目录导航
2、Rxjs入门2
3、Rxjs入门3
4、Rxjs入门4