Rxjs入门1-什么是RxJS、什么是异步、什么情况下会出现异步、异步的缺点、什么是回调、异步回调、异步回调的缺点、Promise的诞生、Promise的缺点

1、什么是RxJS

  • 这里写图片描述 对,这条鱼就是Rx家族的logo,他并不是Rxjs专有的logo,因为Rx家族里面还有RxAndroid、RxSwift、RxNet等等,我也曾询问过网友,问这是条什么鱼,为什么要用这个当logo,最后网友回答最多、最靠谱点的说法就是:这是条鳗鱼,设计这个logo是为了突出rxjs很优雅的链式调用语法,具体情况还不清楚。
  • Rx.JS是英文Reactive Extensions for JavaScript 的缩写。英文水平好的人可以翻译出来rxjs的中文意思是**JavaScript的响应式扩展 **,那什么是"响应式"?一个人看你不顺眼打了你一下,你立马回应(响应)他两个字"滚蛋",像这种你有变化,其他东西会立马跟着响应的方式就叫做"响应式"。
  • 官方也给了对Rxjs的解释:Rxjs是使用 Observables 的响应式编程的库,它使编写异步或基于回调的代码更容易。前半句中Observables是个什么东西在下面再讲,咱们先看看后半句说的它能使异步和回调编写的更容易,也就是说他里面肯定有比之前咱们用到的异步和回调方式好的地方对不对,那下面咱们先温故下异步和回调。

2、什么是异步

	foo();
	bar();

程序运行一般是同步的(synchronous),在上述例子中,如果bar 方法在 foo 方法执行完之后,再执行,这就是同步;如果先执行 foo 方法,foo 方法没执行完,就开始执行 bar 方法,这就成了异步。

3、什么情况下会出现异步

我们都知道 JS 是一个单线程的语言,永远只有一个通道在运行程序。那么既然它是个单线程又如何会有异步呢?咱们先看看一下代码:

var foo = function () {
    console.log('foo begins');
    setTimeout(function () {
        console.log('foo finishes');
    }, 1000);
};
var bar = function () {
    console.log('bar executed');
}
foo();
bar();

先想想会输出什么样的结果,再看答案,输出结果如下:
Rxjs入门1-什么是RxJS、什么是异步、什么情况下会出现异步、异步的缺点、什么是回调、异步回调、异步回调的缺点、Promise的诞生、Promise的缺点_第1张图片
在这种情况下,foo finishes 并没有按顺序输出来,而是等bar()方法里的bar executed 输出来之后才输出,这样就形成了异步情况。

4、异步的缺点

  • 按照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();
    

想想这段代码会出现什么情况?
Rxjs入门1-什么是RxJS、什么是异步、什么情况下会出现异步、异步的缺点、什么是回调、异步回调、异步回调的缺点、Promise的诞生、Promise的缺点_第2张图片
bar函数遇到死循环 foo finishes输出不出来,这就很尴尬了。带着异步的这些缺点咱们再看看回调

5、什么是回调

看看这段代码:

var foo = function (callback) {
    callback();
};

var bar = function () {
    console.log('bar executed');
};

foo(bar);

其中,bar 就是一个回调函数。具体说是 bar 是 foo 的回调函数。

6、异步回调

咱们看这段代码:

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);

输出结果如下:
Rxjs入门1-什么是RxJS、什么是异步、什么情况下会出现异步、异步的缺点、什么是回调、异步回调、异步回调的缺点、Promise的诞生、Promise的缺点_第3张图片
定睛一看,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);

输出结果如下:
Rxjs入门1-什么是RxJS、什么是异步、什么情况下会出现异步、异步的缺点、什么是回调、异步回调、异步回调的缺点、Promise的诞生、Promise的缺点_第4张图片
foo finishes 并没有因为bar函数的死循环而输不出来,这样异步的上述缺点都可以用这种方式来解决了,像这种带有异步的回调方法统称为 异步回调

7、异步回调的缺点

想像一下,如果我们所传递的回调函数也是一个异步操作,也需要传入一个回调函数来处理异步结果怎么办?咱们就应该会这样写出来:

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);

输出:Rxjs入门1-什么是RxJS、什么是异步、什么情况下会出现异步、异步的缺点、什么是回调、异步回调、异步回调的缺点、Promise的诞生、Promise的缺点_第5张图片
像这样一层套一层,使代码晦涩难懂、很不优雅。对于异步回调这种一层层嵌套的现象网上起了个名字叫回调地狱。于是下面就诞生了Promise。

8、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);
});

输出:Rxjs入门1-什么是RxJS、什么是异步、什么情况下会出现异步、异步的缺点、什么是回调、异步回调、异步回调的缺点、Promise的诞生、Promise的缺点_第6张图片
其中,resolve(value)是在Promise在已经异步完成成功(Resolved)之后执行的
reject(value)是在Promise在异步失败之后(Rejected)执行。
当然,也可以用then来指定:then(resolve,reject)
或者:then(resolve),catch(reject)
这样promise很好的将异步回调的这种嵌套式调用转变成了链式调用,使得代码的可读性、维护性提高。

9、Promise的缺点

一旦调用了resolve或者reject之后便返回了,不能再次调用resolve或者reject,想象一下,若是从端口源源不断地发来消息,每次收到消息就要通知回调函数来处理,该怎么办呢?

相关链接

1、程序员分类目录导航
2、Rxjs入门2
3、Rxjs入门3
4、Rxjs入门4

你可能感兴趣的:(JavaScript)