美文网首页javascript
吃透这些例子 包你掌握js执行顺序及promise知识

吃透这些例子 包你掌握js执行顺序及promise知识

作者: 该帐号已被查封_才怪 | 来源:发表于2018-06-06 18:14 被阅读17次

    先来个例子

    一、例子1

    setTimeout(function(){
        console.log('4定时器开始啦')
    });
    
    new Promise(function(resolve){
        console.log('1马上执行for循环啦');
        for(var i = 0; i < 10000; i++){
            i == 99 && resolve();
        }
    }).then(function(){
        console.log('3执行then函数啦')
    });
    
    console.log('2代码执行结束');
    
    

    先别看下面的答案,自己先想想执行顺序。

    image.png

    二、例子2

    如果把 console.log('2代码执行结束'); 放在最前面呢?

    console.log('2代码执行结束');
    
     setTimeout(function(){
        console.log('4定时器开始啦')
    });
    
    new Promise(function(resolve){
        console.log('1马上执行for循环啦');
        for(var i = 0; i < 10000; i++){
            i == 99 && resolve();
        }
    }).then(function(){
        console.log('3执行then函数啦')
    });
    
    
    image.png

    三、例子3

    
    console.log(1)
    
    setTimeout(function(){
            console.log(5)
    })
    
    Promise.resolve().then(function(){
            console.log('promise3')
    }).then(function(){
            console.log('promise4')
    })
    
    console.log(2)  
    
    image.png

    四、例子4

    
      console.log(1)
    
      setTimeout(() => {
        console.log(5)
      })
    
      new Promise((resolve, reject) => {
        console.log(2); for (let i = 0; i < 10000; i++) {
          i == 99 && resolve();
        }
      }).then(() => {
        console.log('promise4')
      })
    
      console.log(3)
    
    image.png

    五、例子5

      console.log(1)
    
      setTimeout(() => {
        console.log(5)
      })
    
      new Promise((resolve, reject) => {
        console.log(2);
        setTimeout(() => {
          console.log(4);
          resolve()
        }, 6000)
      }).then(() => {
        console.log('promise5')
      })
    
      console.log(3)
    
    image.png

    六、例子6

      setTimeout(() => {
        console.log('3setTimeout');
      })
    
      new Promise((resolve) => {
        console.log('1promise');
        setTimeout(() => {
          resolve()
        }, 3000)
      }).then(() => {
        console.log('4then');
      })
    
      console.log('2console');
    
    
    image.png

    七、例子7

        console.log('1111111');
        setTimeout(() => {
          console.log('4----');
          new Promise((resolve) => {
            console.log('5-----');
            resolve();
          }).then(() => {
            console.log('6----')
          })
        })
    
        new Promise((resolve) => {
          console.log('22222');
          resolve();
        }).then(() => {
          console.log('33333-----')
        })
    
        setTimeout(() => {
          console.log('77777');
          new Promise((resolve) => {
            console.log('888');
            resolve();
          }).then(() => {
            console.log('9999999')
          })
        })
    
    image.png

    八、例子8

    这个例子有点难度:

       
        const first = () => (new Promise((resolve, reject) => {
          console.log(11111);
          const p = new Promise((resolve, reject) => {
            console.log('222222' + 'new Promise');
            setTimeout(() => {
              console.log(66666);
              resolve('77777--0000'); // 虽然这里又有一次p的 resolve 但是p的then的语句不会再执行了
            }, 0)
            resolve('4444444' + 'p');
          });
          resolve('555555' + 'first');
          p.then((arg) => {
            console.log(arg); // p 第一次被resolve后 第二次再resolve 不会再执行了
          });
        }));
    
        first().then((arg) => {
          console.log(arg);
        });
        console.log(333333);
    
    image.png

    上面有一点值得注意,就是p的状态一旦改变了(resolve)就不会再改变了,所以 resolve('77777--0000')不会执行了

    九、例子9 (promise状态不可逆性)

    
    var p1 = new Promise(function(resolve, reject){
      console.log('我是p1 我会立即执行')
      resolve("success1");
      resolve("success2");
    });
    
    var p2 = new Promise(function(resolve, reject){
      console.log('我是p2 我会立即执行')
      resolve("success");
      reject("reject");
    });
    
    p1.then(function(value){
      console.log(value);
    });
    
    p2.then(function(value){
      console.log(value);
    });
    
    image.png

    十、例子10

    var p = new Promise(function(resolve, reject){
      console.log("1create a promise");
      resolve("3success");
    });
    
    console.log("2after new Promise");
    
    p.then(function(value){
      console.log(value);
    });
    
    image.png

    十一、例子11 链式调用返回值

    
    var p = new Promise(function(resolve, reject){
      resolve(1);
    });
    p.then(function(value){               //第一个then
      console.log(value);// 1
      return value*2;//2
    }).then(function(value){              //第二个then
      console.log(value+3);//5
    }).then(function(value){              //第三个then
      console.log(value+"后面是 return Promise.resolve('resolvePromise')");// resolvePromise
      return Promise.resolve('resolvePromise');//
    }).then(function(value){              //第四个then
      console.log(value+'后面是 return Promise.reject(\'rejectPromise\')');//  rejectPromise
      return Promise.reject('rejectPromise');//
    }).then(function(value){              //第五个then
      console.log('resolve: '+ value);
    }, function(err){
      console.log('reject: ' + err); // reject:rejectPromise
    })
    
    image.png

    十二、例子12 回调异步性

    var p = new Promise(function(resolve, reject){
      console.log('我最先执行')
      resolve("我在console.log(\"which one is called first ?\")后执行");
    });
    
    p.then(function(value){
      console.log(value); //
    });
    
    console.log("which one is called first ?");//
    
    image.png

    十三、例子13 Promise 中的异常

    var p1 = new Promise( function(resolve,reject){
      foo.bar();
      resolve( 1 );
    });
    
    p1.then(
      function(value){
        console.log('p1 then value: ' + value);//
      },
      function(err){
        console.log('p1 then err: ' + err);
      }
    ).then(
      function(value){
        console.log('p1 then then value: '+value); //
      },
      function(err){
        console.log('p1 then then err: ' + err);
      }
    );
    
    var p2 = new Promise(function(resolve,reject){
      resolve( 2 );
    });
    
    p2.then(
      function(value){
        console.log('p2 then value: ' + value);
        foo.bar();
      },
      function(err){
        console.log('p2 then err: ' + err);
      }
    ).then(
      function(value){
        console.log('p2 then then value: ' + value);
      },
      function(err){
        console.log('p2 then then err: ' + err);
        return 1;
      }
    ).then(
      function(value){
        console.log('p2 then then then value: ' + value);
      },
      function(err){
        console.log('p2 then then then err: ' + err);
      }
    );
    
    
    image.png

    上面值得注意的是 p1、 p2 的多级then回调函数是交替进行的

    十四、例子 Promise.resolve()

    
    var p1 = Promise.resolve( 1 );
    var p2 = Promise.resolve( p1 );
    var p3 = new Promise(function(resolve, reject){
      resolve(1);
    });
    var p4 = new Promise(function(resolve, reject){
      resolve(p1);
    });
    
    console.log(p1 === p2);
    console.log(p1 === p3);
    console.log(p1 === p4);
    console.log(p3 === p4);
    
    p4.then(function(value){
      console.log('p4=' + value);
    });
    
    p2.then(function(value){
      console.log('p2=' + value);
    })
    
    p1.then(function(value){
      console.log('p1=' + value);
    })
    
    image.png

    上面说明下:1、p3 和p4 不和其他相等 是因为 new 出来的对象 不会相等;2、console.log('p4=' + value); 放在最前面 但是最后执行 是因为 p4里面要resolve p1 而p1 又是一个Promise对象,resolve会对p1”拆箱“ 进而获取p1的状态值 但是这是个异步过程 因此 它最后执行;

    十五、例子 15 resolve vs reject 拆箱功能

    var p1 = new Promise(function(resolve, reject){
      resolve(Promise.resolve('resolve'));
    });
    
    var p2 = new Promise(function(resolve, reject){
      resolve(Promise.reject('reject'));
    });
    
    var p3 = new Promise(function(resolve, reject){
      reject(Promise.resolve('resolve'));
    });
    
    p1.then(
      function fulfilled(value){
        console.log('p1 fulfilled: ' + value);
      },
      function rejected(err){
        console.log('p1 rejected: ' + err);
      }
    );
    
    p2.then(
      function fulfilled(value){
        console.log('p2 fulfilled: ' + value);
      },
      function rejected(err){
        console.log('p2 rejected: ' + err);
      }
    );
    
    p3.then(
      function fulfilled(value){
        console.log('p3 fulfilled: ' + value);
      },
      function rejected(err){
        console.log('p3 rejected: ' + err);
      }
    );
    
    
    image.png

    这里稍微解释下 1、为啥p3在最后写 却最先执行了 因为p3 执行的是reject 所以其不需要进行拆箱,因此不会像p1和p2 那样需要拆箱才能异步拿到结果;2、为啥p2 没有执行 fulfilled 回调 因为 p2 在创建时 拆箱得到的结果是reject 因此走的是 rejected 函数的回调而不是fulfilled ;

    参考及推荐资料

    1、这一次,彻底弄懂 JavaScript 执行机制
    2、一个Promise面试题
    3、八段代码彻底掌握 Promise

    相关文章

      网友评论

        本文标题:吃透这些例子 包你掌握js执行顺序及promise知识

        本文链接:https://www.haomeiwen.com/subject/snmbsftx.html