Home > Archives > 详解Promise执行

详解Promise执行

Publish:

之前一直对Promise的概念有一点模糊不清,Promise究竟是怎样异步执行的?Promise为什么表示一个期望?

看了很多书也感觉没有悟透,没想到今天读《深入理解ES6》的时候,突然有了一种理解的感觉,下面我记录一下我的理解。

请看下面一段代码:

const fs = require('fs')

function readFile(filename) {
    return new Promise(function (resolve, reject) {
        fs.readFile(filename, {encoding: 'utf8'}, (err, contents) => {
            if (err) {
                reject(err)
                return
            }
            resolve(contents)
        })
    })
}

const promise = readFile('example.txt')

之前我一直搞不清楚的一个概念是,readFile这个函数返回一个promise,那么这里的Promise构造函数的第一个callback(根据《深入理解ES6》的解释,下文称它为执行器)到底是什么时候执行的?这里怎样实现了异步呢?

不过突然一动念,感觉就拿常规的构造函数执行的套路来理解就可以了,下面我就阐述一下:

return new Promise(exeFunc)

首先这一条语句的意思是,返回一个新建的promise对象,这个对象表达一个意思,我承诺我在将来的一个时间点上会resolve或者reject。这就表示了一个期望。

而这条语句具体的执行过程是这样的:

1)首先,new Promise通过执行exeFunc来创建一个新的promise对象,当触发异步操作时,并不阻塞而是继续向下执行,直到完成promise对象的创建。

2)将这个promise对象返回,此时这个promise对象的状态是pending。

3)异步操作并不会阻塞后续同步代码的执行,只是在完成后,将回调函数加入到任务队列中,等到执行到该任务时,调用resolve或者reject,此时将then/catch的处理程序加入到任务队列末尾。

请注意,可能有很多人会认为如果在执行器中没有异步操作而是直接resolve或者reject的话,这个promise是同步执行的,但事实并非如此,promise永远异步执行,因为resolve和reject只是把then和catch调用的方法添加到任务队列的最末端。请看下面一段代码:

function createPromise() {
    return new Promise((resolve, reject) => {
        console.log('Executor first')
        resolve()
    })
}

createPromise().then(() => {
    console.log('Then last')
})

console.log('Sync second')

请看执行结果:

image

执行结果已经很清晰的说明了,执行器是立即执行的,当遇到resolve之后将then调用的方法添加到任务队列的最末端,然后继续向下执行,直到把所有同步代码执行完成以后,再执行任务队列最末端的then调用的方法。

声明: 本文采用 BY-NC-SA 授权。转载请注明转自: 详解Promise执行 - 无火的余灰