前端高阶之Promise
1 function Event() { 2 this.callbacks = []; 3 this.results = []; 4 } 5 6 Event.prototype.on = function(callback) { 7 this.callbacks.push(callback) 8 } 9 10 Event.prototype.emit = function(data) { 11 this.results.push(data); 12 this.callbacks.foreach(cb => cb();) 13 }
// 被观察者 class Subject { constractor(name) { this.name = name; this.observers = []; // 存放所有观察者 this.mood = '心情很美丽'; } // 接收观察者 attach(observer) { this.observers.push(observer); } setMood(newMood) { this.mood = newMood; this.observers.forEach(o =>o.update(newMood)); } } class Observer { constructor(name) { this.name = name; } update(newMood) { console.log(newMood); } } let sub = new Subject('girl'); let o1 = new Observer('boy'); let 02 = new Observer('father'); sub.attach(o1); sub.attach(o2); sub.setMood('心情很糟糕');
Promise核心应用、实现
一般解决异步问题
// 1.promise的方法会立即执行 let p1 = new Promise(() => { console.log('promise'); }); console.log('world'); // 2.promise对象创建时候有个初始状态,等待态,pending // then()实例方法 制定promise对象状态改变时确定
实例方法:then()
类方法/静态方法:race()/all()resolve()/reject()
all()
let fs = require('fs');
function read(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, 'utf8', function(err, data) {
if(err) return reject(err);
resolve(data);
})
});
}
// 同时读取多个文件
// all 存储一个数组,并且有序
Promise.all([read('a.txt'), read('b.txt')]).then((res) => {
console.log(res);// 将所有文件内容返回,有序
});
// race() 参数中谁的状态先改变,直接决定最后race()返回的Promise实例状态
Promise.race([read('a.txt'), read('b.txt')]).then((res) => {
console.log(res);// 将第一个执行结束的文件内容返回,无序,只返回一个
});
// resolve() 返回一个成功态的Promise实例
Promise.resolve().then(() => {
console.log(111);
})
Promise.reject().then(() => {
console.log()
})
一个promise实例可以多次调用then,当成功后依次调用
使用链式调用,
-
发生错误后,普通值会传入下一次then的成功回调
-
抛出异常会进入下一次then的失败调用
-
如果返回时promise实例,根据该promise的状态对应调用下一次的then
let promise = new Promise((resolve, reject))
then里面是异步函数,抛出错误
class Promise { constructor(callback(resolveFn, rejectFn)) { this.status = "pending"; this.value = undefined; this.resolveCallbackArray = []; this.rejectCallbackArray = []; let resolveFn = (result) => { // 这里需要用异步执行 if(this.status === 'pending') { this.status = 'resolve'; this.value = result; this.resolveCallbackArray.forEach( item => item(this.value);) } } let rejectFn = (reason) => { if (this.status === 'pending') { this.status = 'reject'; this.value = reason; } } } then = (resolveFn, rejectFn) => { typeof resolve !== 'function' ? resolveFn = (res) => { return res; } : null; typeof rejectFn !== 'function' ? rejectFn = (reason) => { throw new Error(reason); } : null; this.resolveCallbackArray.push(resolveFn); this.rejectCallbackArray.push(function(value) => { }); } catch (rejectedCb) { return this.then(null, rejectedCb); } static all(promiseArr = []) { return new Promise((resolve, reject) => { let index = 0; let res = []; for(let i = 0; i < promiseArr.length; i++) { promiseArr[i].then(val => { index++; res[i] = val; if(index === promisArr.length) { resolve(res); } }, reason => { reject(reason); }); } }); } }
如果返回成功传了一个null值,则会进入undefined

浙公网安备 33010602011771号