阅读 22

【javaScript】深入理解promise

存在的意义

Promise提供了一种异步执行模式,其执行仍然是异步方式的,并没有改变成同步执行模式,只不过让代码写起来读起来像是同步执行一样,增加可读性。

promise代码执行顺序

console.log("main-1");
function foo(param) {
    var p = new Promise((resolve, reject) => {
        console.log("promise-1");
        if (param == 1) { 
            resolve("1")
        } else {
            reject("2")
        }
        console.log("promise-2");
    });
    return p
}

console.log("main-2");

foo(1).then((value) => {
    console.log("then-1");
}).catch((reason) => {
    console.log("catch-1");
})

console.log("main-3");

//执行结果如下:
$ node promise.js
main-1
main-2
promise-1
promise-2
main-3
then-1
复制代码

所以

  1. Promise函数体是在Promise对象创建的时候就被执行了,可以理解为Promise函数是同步执行的。
    由此我们知道resolve或者reject函数已经在Promise函数体内被调用了,而此时resolve和reject的值并没有被定义了,怎么办?其实这就是Promise机制实现的功能,可是先调用一个未定义的函数,等将来函数被定义的时候(即then()将函数体挂到resolve出口)再真正执行函数体。
  2. then/catch函数体并不是在then/catch被调用的时候执行的,而是在后面的某一个异步时间点被执行,这也是Promise机制实现的功能。
    因此定义Promise时指定的函数体是在当场就执行的,而定义then()时指定的函数体不是当场执行,而是在之后以异步的方式执行的,then/catch负责注册这些函数体到对应的resolve/reject函数链上,而不会马上就执行他们,只是注册,等待参数到来时执行函数体。

简单的说

  1. Promise对象创建的时候,立刻执行Promise函数体,同时会标记将来是执行resolve还是reject,Promise对象的最终状态只有两个要么是resolved,要么是rejected,所以如果在Promise函数体里面同时调用了resolve和reject(注意Promise函数体里面不管是调用了resolve还是reject,都不结束函数,而会继续执行后面的代码),谁先调用谁有效,后面调用的无效,因为第一个调用就已经改变了Promise的最终状态。举个例子:
    function foo(param) {
        var p = new Promise((resolve, reject) => {
            //resolve把promise最终状态职位resolved.
            resolve("succ"); 
            
            //reject代码无效,因为Promise的最终状态已经被置为resolved了,此时再置成rejected自然无效
            reject("fail"); 
            
            //log代码正常执行
            console.log("hello");
            
            //这个值不知道返回到哪里去
            return "any";
            
            //不执行
            console.log("world");
        });
        return p
    }
    
    foo(1).then((value) => {
            console.log("then-1: " + value);
    }).catch((reason) => {
            console.log("catch: " + reason);
    })

    //运行结果为:
    $ node p.js
    hello
    then-1: succ
复制代码
  1. then/catch负责注册这些函数体到对应的resolve/reject函数链上,而不会马上就执行他们,只是注册。
  2. 对他们的执行是在稍后以异步事件的方式回调的;具体的回调时间是不确定的。
文章分类
前端
文章标签