前端高阶之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('心情很糟糕');
View Code

Promise核心应用、实现

一般解决异步问题

// 1.promise的方法会立即执行
let p1 = new Promise(() => {
   console.log('promise'); 
});
console.log('world');
// 2.promise对象创建时候有个初始状态,等待态,pending
// then()实例方法 制定promise对象状态改变时确定
View Code

常用API

实例方法: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()
})
View Code

一个promise实例可以多次调用then,当成功后依次调用

使用链式调用,

  1. 发生错误后,普通值会传入下一次then的成功回调

  2. 抛出异常会进入下一次then的失败调用

  3. 如果返回时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); 
               });
           } 
        });
    }
}
View Code

如果返回成功传了一个null值,则会进入undefined

 

posted @ 2020-05-27 09:03  my_jsonal  阅读(176)  评论(0)    收藏  举报