理解了这些才能理解Promise
promise的文章有很多,但大多数对于像我一样的菜鸟来说还是过于晦涩,我觉得一个初学者理解promise的最好方式就是不妨臆想一下promise是在哪一种契合下产生并发展的?
promise中文翻译过来是”承诺“的意思,”承诺”是对未来的一种许诺,而promise就是对未来应对不同的情况执行不同js代码的一种许诺.这个未来就是指稍后某一刻将要执行的js代码,而在js中”稍后执行”意味着它不会阻塞当前js代码,也可以说这段代码是异步的.
在了解promise之前需要了解几个简单的知识
(1)javascript的异步编程
在多线程的语言中最容易想到的异步方式就是在当前线程中,新创建一个线程让某段代码片段运行在新创建的线程中,从而使当前线程继续向下执行,但在javascript的世界里,异步是指那些”稍后执行”的代码片段,因为是”稍后执行”所以不会阻塞当前代码的执行,最明显的一个例子就是事件回调,它会在相应事件触发的那一刻执行,而不会在定义它的地方执行.
(2)javascript的线程模型
任何一本书关于js的书都会告诉我们js是运行在单线程里的,这个线程称为UI线程,从名字就知道这个线程不光用于运行js代码,还负责事件的处理和UI的绘制. 在游览器内部维护着一个事件队列,触发的事件会一个个的放进这个队列中,UI线程在空闲时会去查看这个队列,如果队列不为空,就取第一个事件并执行其监听函数.
for (var i = 0; i < 3; ++i) {
setTimeout( function(){
console.info( 'setTimeout: ' + i);
}, 16);
console.info( 'for循环: ' + i)
}
你能正确说出控制台打印的内容么?
下面是这个代码片段的执行示意图.
首先将此段js代码放进UI线程中执行,当代码执行到setTimeout(fn, mills)时,游览器会在事件队列中放入此定时事件1,前面说过只有当UI线程空闲时才会去执行定时事件,但此时js代码还在执行,所以继续for循环,i继续自增,并且继续放入定时事件2,3,当js代码片段执行完毕后,才继续依次执行定时事件1、2、3,此时i的值已经是3了.所以在控制台中我们看到的打印结果依次是:
for循环:0
for循环:1
for循环:2
setTimeout:3
setTimeout:3
setTimeout:3
再说回promise,promise就是为了处理异步函数导致的两个问题而生,并且稍后你会了解到promise能对异步函数进行聚集并且提供一种”承诺”,本身就是通过js的异步模型实现的。
下次我们来对一个最基本的“回调地狱”进行改善来看看promise是如何产生的。