谈到promise,首先你们应该了解promise的主要做用是解决异步加载的问题。promise
##关于异步异步
所谓"异步",简单说就是一个任务不是连续完成的,能够理解成该任务被人为分红两段,先执行第一段,而后转而执行其余任务,等作好了准备,再回过头执行第二段。async
好比,有一个任务是读取文件进行处理,任务的第一段是向操做系统发出请求,要求读取文件。而后,程序执行其余任务,等到操做系统返回文件,再接着执行任务的第二段(处理文件)。这种不连续的执行,就叫作异步。函数
相应地,连续的执行就叫作同步。因为是连续执行,不能插入其余任务,因此操做系统从硬盘读取文件的这段时间,程序只能干等着。简单的说同步就是你们排队工做,异步就是你们同时工做。 ##Promise A+规范的 Promise 为了便于理解,本文将分为三个部分,每一个部分实现 Promise 的一部分特性,最终一步一步的实现一个完整的、遵循 promise A+ 规范的 Promise。Promise A+ 规范规定,Promise 有三种状态,分别是 pending(默认状态,表明等待)、fulfilled(表明成功)、rejected(表明失败)。来看看 Promise 的用法,以及它有哪些特性。 var fn = new Promise(function (resolve, reject) {
// 异步操做
setTimeout(function() {
resolve('111')
// 因为reslove和 reject 是互斥的,由于已经调用了 resolve,这里reject不会执行 reject('111') }, 500) }) fn.then(function (data) { console.log('成功1:', data) return new Promise(function (resolve, reject) { reject('reject 02') } )}, function (err) { console.log('失败1:', err) }) .then(function (data) { console.log('成功2:', data) }, function (err) { console.log('失败2:', err) }).then(function (data) { console.log('成功2:', data)}, function (err) { console.log('失败2:', err) })ui
1.Promise 类有 then 方法,then 方法有三个参数,分别是 Promise 成功和失败的回调以及pending初始状态this
2.Promise 支持链式调用,then 的返回值能够是一个 Promise,也能够是一个普通值,若是是 一个普通的值,那么就会当作下一个 then 成功的回调函数的参数操作系统
3.Promis 还有其它扩展方法code
##接下来咱们简单了解一下promise的一些封装原理cdn
class Promise {
constructor(executor) { //定义初始状态 this.status = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = [];//返回成功回调函数
let resolve = (data) => { // 加载数据判断成功 if (this.status === 'pending') { this.value = data; this.status = 'resolved'; this.onResolvedCallbacks.forEach(fn => fn()); } } let reject = (reason) => { // 加载数据判断失败 if (this.status === 'pending') { this.reason = reason; this.status = 'rejected'; this.onRejectedCallbacks.forEach(fn => fn()); } }`对象
try { executor(resolve, reject); } catch (e) { reject(e); } }
then(onFulFilled, onRejected) { onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : y => y; onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; }; let promise2; if (this.status === 'resolved') { promise2 = new Promise((resolve, reject) => { setTimeout(() => { try { let x = onFulFilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }, 0); }); } if (this.status === 'rejected') { promise2 = new Promise((resolve, reject) => { setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e); } }, 0); }); } if (this.status === 'pending') { promise2 = new Promise((resolve, reject) => { this.onResolvedCallbacks.push(() => { setTimeout(() => { try { let x = onFulFilled(this.value); resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e); } }, 0) }); // 存放失败的回调 this.onRejectedCallbacks.push(() => { setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }, 0); }); }) } return promise2; // 调用then后返回一个新的promise } // catch接收的参数 只用错误 catch(onRejected) { // catch就是then的没有成功的简写 return this.then(null, onRejected); } }
Promise.resolve = function (val) { return new Promise((resolve, reject) => resolve(val)) }
Promise.reject = function (val) { return new Promise((resolve, reject) => reject(val)); }
了解了promise的原理,接下来给大家扩展一下promise番外篇,async-await函数和Generator 函数
1.Generator 函数
Genrator 函数要用* 来比标识,yield关键字表示暂停。将函数分割出好多个部分,调用一次next就会继续向下执行。返回结果是一个迭代器,迭代器有一个next方法。
function* read() { console.log(1); let a = yield '123'; console.log(a); let b = yield 9 console.log(b); return b; } let it = read(); console.log(it.next('213')); // {value:'123',done:false} console.log(it.next('100')); // {value:9,done:false} console.log(it.next('200')); // {value:200,done:true} console.log(it.next('200')); // {value:200,done:true}
yield后面跟着的是value的值,yield等号前面的是咱们当前调用next传进来的值,而且第一次next传值是无效的。
处理异步的时候Generator和Promise搭配使用
let bluebird = require('bluebird'); let fs = require('fs'); let read = bluebird.promisify(fs.readFile);//将readFile转为Promise对象的实例 function* r() { let content1 = yield read('./2.promise/1.txt', 'utf8'); let content2 = yield read(content1, 'utf8'); return content2; }
2.async-await函数
let bluebird = require('bluebird'); let fs = require('fs'); let read = bluebird.promisify(fs.readFile);
async function r(){ try{ let content1 = await read('./2.promise/100.txt','utf8'); let content2 = await read(content1,'utf8'); return content2; }catch(e){ // 若是出错会catch console.log('err',e) } }
以上是我对promise的理解,但愿有什么错误能够指正。