Promise的学习

1.JS是单线程,但是为什么是单线程呢?

因为我们需要能够通过操作DOM方式,为了防止DOM冲突【假设JS是多线程,那么它可以同时执行多个任务,如果这多个任务都是操作DOM,也就是说可能存在多种不同的DOM操作,而且这些操作同时执行】,所以必须把JS设置成单线程。

 

异步任务在单线程中是事件轮询通过回调的方式来实现的。

 

2.事件轮询是什么?

浏览器通过JS脚本执行,JS脚本中执行任何任务有个叫调用栈(call Stack)的东西,所有任务都放Call Stack中,异步任务直接在Call Stack调用,调用完放Web APIs中,比如setTimeout,几秒后,把里面的回调函数放到CallBack queue中,当Call Stack里面为空,轮询机制就往CallBack queue中查看有没有任务,有执行。如此反复。

题目:

console.log('hi')

setTimeout(function cb1(){

   console.log('cb1');

},5000)

console.log('bye');

 

顺序:

1.

2. setTimeout放进去,然后开启一个计时器timer,Call Stack清空,计时结束后,把cb1 放到Callback队列中,然后通过事件轮询方式,cb1放到Call Stack,再执行逻辑

3.打印console.log('bye')

顺序就是:hi bye cb1

 

3.什么是回调函数?

参数是函数的函数是回调函数,比如

arr.sort(function(a,b){}  ),参数是回调函数。常见的回调函数有setTimeout(function(){})、$ajax({  success:function(){}  })等。

但是回调函数不一定都是异步函数。存在同步回调函数和异步回调函数。计数器执行完后才执行这个方法,ajax也是成功后才执行,所以他们都是异步回调函数。sort里是同步回调函数。

 

4.迭代和遍历有什么区别?

迭代:从目标源依次逐个抽取的方式提取数据

遍历:只要循环所有数据就行

 

 迭代:

function myIterator(arr){

  var index=0;

  return{

    next(){

       if(index<arr.length){

          return{

            value:arr[index++],done:false

         }

    }

   return { value:undefined,done:true };

  }

 }

}

 

生成器【function *】是为了生成迭代器。——解决对象没有symbol.iterator属性的问题【不能用for of遍历对象】

yield能中断函数的执行:

function* test(){

  console.log(1);

  yield 1;

  console.log(2)

}

var item=test();

console.log(item.next());

 

function* test(){

 let value1=yield 1;【传值方式是红色箭头】

 console.log(value1);---‘two’

 let value2=yield 2;

 console.log(value2);

}

var ite=test();

console.log(ite.next('one'));

console.log(ite.next('two'));

 

async函数本质上是 生成器函数+执行器函数【就是让value1接收yield1的值】

Promise

Promise有三个状态pending进行中、fulfilled已完成、rejected已失败,两个阶段:pending到fulfilled和pending到rejected

通过resolve()改变状态pending到fulfilled,通过reject()把状态从pending改成rejected

function readFile(pathname){

  return new Promise(function (resolve,reject){

     fs.readFile(pathname,'utf-8',function(err,data){

        if(err){

         reject(err);

         return;

       }

      resolve(data);

   });

 })

}

let promise=readFile('./name.txt');

promise.then(function(data){-----------如果成功就会把上面resolve(data)的data传进这里,且执行

  

},function(err){-----同理

 

})

 

总结:1.promise状态不受外界影响

          2.状态一旦改变就不能更改

 

      let promise=new Promise(function(resolve,reject){
        console.log('promise');
        resolve('resolve');//微任务,优先执行微任务
      })

      setTimeout(function(){//异步任务
        console.log('timeout');
      },0);

      promise.then(function (data){
        console.log(data);
      }) 

      console.log('hi');

打印结果:

promise

hi

resolve

timeout

 

     let p1=Promise.resolve(1);
     let p2=Promise.reject(2);

     p1.then(function(data){
       console.log(data);
     })

    //  p2.then(function(){

    //  },function(err){
    //    console.log('err'+err);
    //  })
    p2.catch(function(err){
      console.log('err'+err);
    })

打印:

1

err2

 

thenable对象

let obj={

  then(resolve,reject){

    reject(11);

  }

}

let p1=Promise.resolve(obj);----当绑定一个参数为thenable对象时,会默认调用对象的then方法。

p1.then(function(data){

   console.log(data);

},function(err){

  console.log('err'+data);---输出err11

})

 

let obj={

  then(resolve,reject){

    reject(11);

  }

}

let p1=Promise.reject(obj);----在reject不会调用

p1.then(function(data){

   console.log(data);

},function(err){

  console.log('err'+data);

})

Promise.resolve().then()(function(){

 console.log('promise1');

  setTimeout(()=>{

      console.log('setTimeout2');

  },0)

})

setTimeout(()=>{

   console.log('setTimeout1');

   Promise.resolve().then()(function(){

     console.log('promise2');

   })

},0);

输出:

promise1

setTimeout1

promise2

setTimeout2

 

链式调用

let p1=new Promise((resolve,reject)=>{

   resolve(1);

})

p1.then(res=> res+1 )

    .then(res=> res+1)

   .then(res => { console.log(res+1) ;return res+1})-------输出4

let p1=new Promise((resolve,reject)=>{
  resolve(1);
  reject(10);
})

p1.then(res=> console.log(res))-----输出1
  .then()
  .then()
  .then(res=> console.log(res))----输出undefined
  .catch(err =>console.log(err))

状态依赖

当存在状态依赖,自身状态就会无效。

const p1=new Promise((resolve,reject)=>{

   setTimeout(()=>{ 

      reject('1000');

    },2000)

})

const p2=new Promise((resolve,reject)=>{

   setTimeout(()=>{

     resolve(p1);----这里的状态无效,由依赖p1决定,p1成功它就成功,反之同理

  },1000)

})

p2.then(res => console.log(res))

    .catch(err =>console.log(err));---输出1000

 

Promise.all 和Promise.race

all:等最慢的,必须所有都是true(resolve)

race:找最快的,如果最快的是reject,那就执行.then的第二个函数

      let p1=new Promise((resolve,reject)=>{
        setTimeout(()=>{
          resolve(10)
        },1000)
      })

      let p2=new Promise((resolve,reject)=>{
        setTimeout(()=>{
          resolve(20)
        },2000)
      })

      let p3=new Promise((resolve,reject)=>{
        setTimeout(()=>{
          resolve(30)
        },3000)
      })

      let p4=Promise.all([p1,p2,p3]);---所有的promise都拿到结果后,p4才会拿到最终结果
      p4.then(res=>{
        console.log(res);
      })

asycn和await

async函数本质上是 生成器函数+执行器函数

 

async function readSync(){

  let value1=await readFile('./name.text','urf-8');

  let value2=await readFile(value1,'utf-8'); 

  let value3=await readFile(value2,'utf-8');

  return value3;

}

let promise1=readSync();

promise1.then(function(res){

   console.log(res);

})

 

如果asycn定义的函数有返回值xxx,就相当于resolve(xxx):

async function demo01() {
    return 123;
}

demo01().then(val => {
    console.log(val);// 123
});

如果没有返回值,相当于resolve()

async function demo01() {
    console.log("withOut return")
}

demo01().then(val => {
    console.log(val);// undefined
});

如果 await 的是 promise对象,await 会暂停 async 函数内后面的代码,先执行 async 函数外的同步代码(注意,promise 内的同步代码会先执行),等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果返回后,再继续执行 async 函数内后面的代码

function sleep(second) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(' enough sleep~');
        }, second);
    })
}
async function awaitDemo() {
    let result = await sleep(2000);
    console.log(result);// 两秒之后会被打印出来
}
console.log("主线程1")
awaitDemo();
console.log("主线程2")
//主线程1
//主线程2
//enough sleep~

如果 await 的不是一个 promise ,而是一个表达式。await 会暂停 async 函数内后面的代码执行,先执行 async 函数外的同步代码(注意,此时会先执行完 await 后面的表达式后再执行 async 函数外的同步代码)

function sleep(second) {
 	return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(' enough sleep~');
        }, second);
    })
}
function normalFunc() {
    console.log('normalFunc');
}
async function awaitDemo() {
    await normalFunc();
    console.log('something, ~~');
    let result = await sleep(2000);
    console.log(result);// 两秒之后会被打印出来
}
console.log("主线程1")
awaitDemo();
console.log("主线程2")
//主线程1
//normalFunc
//主线程2
//something, ~~
//enough sleep~

混用:

async function async1() {
  console.log('async1 start')// 2  主线程async1()调用
  await async2()
  console.log('async1 end')  // 6 主线程内同步代码执行完毕后接着执行await函数内后面的代码(至此主线程内同步代码都执行完毕)
}

async function async2() {
  console.log('async2')// 3 主线程async1() => async2()  await 会先执行完async2()内的代码
}

console.log('script start')// 1  主线程同步代码
setTimeout(function() { 
  console.log('setTimeout') // 8 setTimeout放入宏队列中下次轮询执行
}, 0)

async1(); 
  
new Promise( function( resolve ) {
  console.log('promise1') // 4 promise内的同步代码会在主线程内先执行
  resolve();
} ).then( function() {
  console.log('promise2') // 7 promise回调会放入微队列中,主线程代码执行完毕后执行
} )

console.log('script end') // 5 主线程同步代码
//script start
//async1 start
//async2
//promise1
//script end
//async1 end
//promise2
//setTimeout

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值