promise.then

2020-03-12  本文已影响0人  看到这朵小fa了么

https://cloud.tencent.com/developer/article/1361997

promise的then做了什么

学习: https://segmentfault.com/a/1190000010420744?utm_source=tag-newest

let func = function() {
    return new Promise((resolve, reject) => {
        resolve('返回值');
    });
};

let cb = function() {
    return '新的值';
}
// 是函数 则将函数的返回值cb() 执行了 的值返回给下一个then
func().then(function () {
    return cb();
}).then(resp => {
    console.warn(resp); // 新的值
    console.warn('1 =========<');
});
// 执行了 但是没有返回值
func().then(function () {
    cb();
}).then(resp => {
    console.warn(resp); // undefined
    console.warn('2 =========<');
});
// 是一个值 被忽略 返回了上一个then resolve的值
func().then(cb()).then(resp => {
    console.warn(resp); // 返回值
    console.warn('3 =========<');
});
// 是一个函数且有返回值 
func().then(cb).then(resp => {
    console.warn(resp);  // 新的值
    console.warn('4 =========<');
});

promise.then接受一个promise对象

  Promise.resolve('foo')
  //第一个promise已经resolve,将'foo'传入第一个then。
  .then(function(string) {
    return new Promise(function(resolve, reject) {
      setTimeout(function() {
        string += 'bar';
        resolve(string);
      }, 1000);//将1ms改为1s更易观察
    });
  })
// @1
  .then(function(string) {
    setTimeout(function() {
      string += 'baz';
      console.log(string);
    }, 1000)
    return string;
  })
//@2
  .then(function(string) {
    console.log("Last Then:  oops... didn't bother to instantiate and return " +
                "a promise in the prior then so the sequence may be a bit " +
                "surprising");
    console.log(string);
  });
  //由于第二个then中return的string值为'foobar',因此先输出'foobar'。
// 并在前面的1s定时结束后执行string += 'baz', 最后输出foobarbaz。

实现一个promise

class simplePromise {
    constructor(exec) {
        this.status = 'pending'
        this.value = undefined
        this.reason = undefined
        this.fullfillCalls = []
        this.rejectCalls = []
        let that = this
        function resolve(value) {
            // 状态只能从pending到 fullfilled 或者pending到rejected
            if (that.status !== 'pending') return
            // 真正的promise可能是通过其他延迟实现,
            // 我的理解是这里resolve并不会直接结束而是要去执行一些其他的同步语句
            // 如果有异步的话 可能要等待所有异步的完成?
            setTimeout(() => {
                that.status = 'fullfilled'
                that.value = value
                // then是可以连续回调的
                that.fullfillCalls.forEach(fn => fn && fn(value))
            })

        }
        function reject(error) {
            if (that.status !== 'pending') return
            setTimeout(() => {
                that.status = 'rejected'
                that.rejectCalls.forEach(fn => fn && fn(error))
            })

        }

        try {
            // 包装传递进来的函数,传递resolve 和reject函数
            exec(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }  
        // 如果then必须返回一个promise对象,这也是能够链式调用的原因,
        // 如果是pending状态 那么返回的promise状态决定了调用者promise的状态
    then(onFullfill, onReject) {
        // 当then后面传入的不是函数 会被转化为函数?
        onFullfill = typeof onFullfill === 'function' ? onFullfill : value => value
        onReject = typeof onReject === 'function' ? onReject : reason => reason
        if (this.status === 'pending') {
            return new simplePromise((resolve, reject) => {
                this.fullfillCalls.push(onFullfill)
                this.rejectCalls.push(onReject)
            })
        // 当返回fullfilled状态 则立即执行fullfillCalls队列
        } else if (this.status === 'fullfilled') {
            onFullfill(this.value)
            // this.fullfillCalls.forEach(fn => fn && fn(this.value))
        } else if (this.status === 'rejected') {
            onReject(this.reason)
            // this.rejectCalls.forEach(fn => fn && fn(this.reason))
        }
    }
}
// 首先传入的函数被包裹到exec调用then函数,返回一个promise,将then后面的第一个函数压栈
// 等待setTimeout任务完成调用resolve,完成状态转化和函数执行
new simplePromise((resolve, reject) =>{
    setTimeout(() =>{
    resolve(123)
 })
 }).then(value =>{
    console.log(value)
 })

手动添加方法

Promise.prototype.done(callback){
   return this.then(
   value => {this.then(callback()).then(()=>value}
   reason => {this.then(callback()).then(() => throw reason)}
)
}
Array.prototype.add(number){
  return Array.prototype.concat.call(this, number)
}
上一篇 下一篇

猜你喜欢

热点阅读