美文网首页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