Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于Promise的几点疑问&见解 #6

Open
cpdeam opened this issue Aug 29, 2019 · 0 comments
Open

关于Promise的几点疑问&见解 #6

cpdeam opened this issue Aug 29, 2019 · 0 comments

Comments

@cpdeam
Copy link

cpdeam commented Aug 29, 2019

1.为什么resolve/reject里面一定要判断状态?
Promise状态转换后就不可以再改变了,所以这里判断一下状态再决定要不要执行后面的代码;

2.为什么resolve/reject一定要异步执行?
如果不是异步执行,那then注册的回调还没来得及注册(因为then永远是同步调用的),resolve/reject就已经跑完了,因此这里必须用异步。而且规范里说,resolve/reject必须在执行环境(JavaScript)堆栈仅包含平台代码时才可被调用,并且尽可能早的调用,其实也就说最好用微任务(Micro task)去实现,但是不太好实现,所以用了setTimeout去模拟;

3.真正的promise是否是用这种方式实现的?如果不是,那么会是以一种什么方式实现的?
同上,应该是用微任务实现的,但是在不同环境下(浏览器、nodejs等),微任务的实现方式应该不同;

4.为什么要遍历。或者说为什么要用一个calls而不是单独的一个callback来存储
可以通过重复调用then注册多个回调;

5.在then方法里什么参数都没有或者传入一些奇奇怪怪的东西的时候,promise会做哪些操作?
也就是Promise的值穿透,规范就是这么定义的。然后这里

 rejectFn = typeof rejectFn === 'function' ? rejectFn : reason => reason

改成

 rejectFn = typeof rejectFn === 'function' ? rejectFn : reason => { throw reason }

应该更合适一些

6.为什么then里面还要判断状态?
因为then是同步调用,但是Promise里面可能有异步,所以进入then的时候,可能还在pending;
既然resolve/reject是异步,那岂不是说调用then时,基本上都是pending了?并且resolve/reject还必须在then方法被调用的那一轮事件循环之后的新执行栈中调用,规范2.2.4;此处确实无法理解为何在then里需要判断Promise是否为resolved/rejected状态

7.then里面为resolved/rejected状态时的处理
这个有点麻烦。。。必须返回一个新的promise,并且其状态依赖当前promise的状态;

8.我的疑问

  • 如何让返回的promise依赖当前promise的状态;
  • trycatch不能捕获回调里的错误,那如果resolve时,执行其内部回调时出错了怎么办,用catch吗,那如果没有使用catch,这个错误是不是就没了
  • ES6标准入门一书里有说,Promise还解决了传统事件(Event)的一个问题,那就是事件一旦执行了,再去注册回调是不会生效的,但是考虑如下代码:
const p = new Promise((resolve, reject) => {
  resolve(111)
})

setTimeout(() => {
  p.then(() => {
    console.log(111)
  })
}, 3000);

延时执行then,此时注册的回调岂不是也没有生效吗(实际上生效了)?因为resolve/reject始终是微任务(见第6条),resolve里的代码反而会比setTimeout先执行了,导致此时注册的回调失效了。会出现这种情况吗?还是我的理解错误。
emmm,解释下,不应该按照别人实现promise形式去看promise,其实resolve/reject本身应该不是微任务,应该也算是主代码块的一部分,只是then确实是微任务。我刚才把resolve/reject本身也误认为是微任务了。

9.关于finally的polyfill
网上一般都是这么写的:

Promise.prototype.finally = function(callback) {
  return this.then(
    value => this.constructor.resolve(callback()).then(() => value),
    reason => this.constructor.resolve(callback()).then(() => {
       throw reason
      })
    )
}

那么 为什么不可以这么写,一定要在then的回调里返回一个新的promise呢:

Promise.prototype.finally = function (callback) {
  return this.then(
    value => {
      callback()
      return value
    }, 
    reason => {
      callback()
      throw reason
    })
}

这个很是疑惑,不解

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant