谈谈Promise的前世此生

前言

谈到Promise,你们都熟烂于心,有的童鞋已经在项目中大规模使用async/await,甚至有的开始用上了fetch。不管什么方式,实质都是Promise的封装和语法糖,因此弄清楚了Promise的前因后果,有助于更好地理解和使用Promise。javascript

历史演变

  • callback
  • observers
  • JSDeferred
  • jQuery Deferred
  • Promise(*)
  • generator
  • async/await
  • fetch

callback

网上曾流传一张这样的图(如上图所示)来形容(callback hell)回调地狱,能够说很生动形象了。代码规范作得好一点的童鞋可能会把回调函数拆开,但若是不谨慎,一不当心就会写出这样的代码来。在刀耕火种年代,回调是最为快捷有效的办法。其思想是把要执行的代码做为函数参数传递,而后在异步代码执行完执行传入的回调函数。

const fetchApi = (callback) => {
    setTimeout(() => {
        //todo something...
        callback && calback();
    }, 1000);
};

fetachApi(() => {
    //some code...
});
复制代码

这样虽然能够解决问题,可是还存在如下几个问题:前端

  • 代码易读性差
  • 代码不紧凑
  • 依然会有callback hell问题

observers

观察者模式,jQuery三行代码搞定发布订阅模式java

//订阅
$.on(document, function() {
    
});
//取消订阅
$.off(document, function() {
    
});
//发布
$.trigger(document, function() {
    
});
复制代码

listeners

EventEmitter

const EventEmitter = require('Event.EventEmitter');
const eventEmitter = new EventEmitter();
eventEmitter.on('data', () => {
    //some code...
});
eventEmitter.emit();
复制代码

DOM事件

document.onclick = function() {
    //some code...
}
复制代码

jQuery事件绑定

$(document).on('click', function() {
    //some code...
})
复制代码

JSDeferred

Promise里程碑,在Promise还没造成规范以前,各大库(mochikit,dojo,jQuery...)百花齐放,都实现了各自的Promise模型。ajax

jQuery Deferred

Promise先驱者,前端新人可能对jQuery比较熟悉,在平时的工做中,据我所知,我身边的前端童鞋几乎都不知道这个jQuery的这个api。其实早在Promise诞生前,jQuery内部已经实现Promise相似功能,只是没有成为规范被归入。json

$.Deferred
$.when()
复制代码

Promise

这个是本文讲述的重点api

const promise = new Promise((resolve, reject) => {
    if (data) {
        resolve(data);
    }else {
        reject(error);
    }
});
promise.then(data => {
   //some code... 
});
Promise.all([fetchApi1, fetchApi2]);
Promise.trace([fetchApi1, fetchApi2]);
复制代码

generator

迭代器模式, async/await过渡产品promise

const loginHandler = *() => {
    yield fetchApi();
}
loginHandler.next();
复制代码

async/await

像写同步代码同样书写异步代码bash

const loginHandler = async () => {
    const data = await fetchApi();
    //do something with data...
};
复制代码

fetch

将来的ajax异步

fetach(apiUrl, data => data.json() => data )
.then(data => {
    //some code...
});
复制代码
相关文章
相关标签/搜索