还是得每天保持学习呀!(一)

(一)知识点 finally:

  • .finally的返回值如果在没有抛出错误的情况下默认会是上一个 Promise 的返回值,有时finally用在了then后面,当then没有返回值时,then返回的promise实例,它resolve出来的值会是undefined。
  • (额,补充一下上面这句话,finally也会返回一个新的promise实例,但这个promise的resolve值在没有抛出错误的情况下默认会是上一个 Promise 的resolve值)
  • finally 方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是 fulfilled 还是 rejected。
const p1 = new Promise((resolve) => {
  resolve('resovle1');
}).then(res => {
  return 'adaa'; // 新的promise实例,其resolve值为'adaa'
}).finally(res => {
  console.log(res); // undefined
  return 'vsv'; // 无用
}).then(res => {
  console.log(res); // adaa  
})
  • 定时器打印promise的时候,如果有then 就打印 then返回的promise实例的resolve值,也就是要在then里面有个return)then没有return任何东西就默认打印promise(< fulfilled >,undefined)。promise没有resolved状态,就是fulfilled状态,然后是rejected,pending。没then就打印promise本身resolve出来的值
const p1 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('resolve3');
    console.log('timer1')
  }, 0)
  resolve('resovle1');
  resolve('resolve2');
}).then(res => {
  console.log(res)  // resolve1
  setTimeout(() => {
    console.log(p1) // promise(<fulfilled> undefined)
  }, 1000)
}).finally(res => {
  console.log('finally', res)
})

需要注意的是最后一个定时器打印出的 p1 其实是.finally 的返回值(BTW如果没有这个finally,定时器打印的promsie值也是undefined,因为then没有返回东西),我们知道.finally的返回值如果在没有抛出错误的情况下默认会是上一个 Promise 的返回值,而这道题中.finally 上一个 Promise 是.then(),但是这个.then() 并没有返回值,所以 p1 打印出来的 Promise 的值会是 undefined,如果在定时器的下面加上一个 return 1,则值就会变成 1

(二)知识点await后面是new promise

  • await后面如果是new promise (一个promsie实例),必须要注意这个promise实例是否resolve了,没有resolve就不会执行后面的代码,包括后面的函数return。
  • then等期望接收一个函数(promise.resolve不是函数,也不会返回一个函数)作为参数,如果发现不是函数,就会发生值透传。否则就不会进行值透传,并按就近原则去找最近的promise对象,等它的状态发生改变后,下面的then才会被调用
const async1 = async () => {
  console.log('async1');
  setTimeout(() => {
    console.log('timer1')
  }, 2000)
  await new Promise(resolve => {
    console.log('promise1')
  })
  console.log('async1 end')
  return 'async1 success'
} 
console.log('script start');
async1().then(res => console.log(res));
console.log('script end');
Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .catch(4)
  .then(res => console.log(res))
setTimeout(() => {
  console.log('timer2')
}, 1000)

输出结果如下:

script start
async1
promise1
script end
1
timer2
timer1

代码的执行过程如下:

  1. 首先执行同步带吗,打印出 script start;
  2. 遇到定时器 timer1 将其加入宏任务队列;
  3. 之后是执行 Promise,打印出 promise1,由于 Promise 没有返回值,所以后面的代码不会执行;
  4. 然后执行同步代码,打印出 script end;
  5. 继续执行下面的 Promise,.then 和.catch 期望参数是一个函数,这里传入的是一个数字,因此就会发生值渗透将 resolve (1) 的值传到最后一个 then,直接打印出 1;
  6. 遇到第二个定时器,将其加入到微任务队列,执行微任务队列,按顺序依次执行两个定时器,但是由于定时器时间的原因,会在两秒后先打印出 timer2,在四秒后打印出 timer1。

知识点(三)then和catch

  • catch和then一样,只要没有throw error 这样的代码,就会返回一个新的成功的promise实例
  • then 方法返回的是一个新的 Promise 实例(注意,不是原来那个 Promise 实例)。
  • 只有在then方法里面return了一个值,那么其随后的then的回调函数才能接受到参数,否则,他们的参数都会是undefined。
const p1 = new Promise((resolve) => {
  resolve('resovle1');
}).then(res => {
  console.log(res)  // resolve1
}).then(res => {
  console.log('finally', res) // finally undefined
})
  • 上面说到每个then都会返回一个新的promise实例,所以后面链式调用到的then都会去看这个新的promise实例,不会去看原始的promise,

采用链式的 then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个 Promise 对象(即有异步操作),这时后一个回调函数,就会等待该 Promise 对象的状态发生变化,才会被调用。

getJSON("/post/1.json").then(function(post) {
  return getJSON(post.commentURL);
}).then(function (comments) {
  console.log("resolved: ", comments);
}, function (err){
  console.log("rejected: ", err);
});

上面代码中,第一个 then 方法指定的回调函数,返回的是另一个 Promise 对象。这时,第二个 then 方法指定的回调函数,就会等待这个新的 Promise 对象状态发生变化。如果变为 resolved,就调用第一个回调函数,如果状态变为 rejected,就调用第二个回调函数。

知识点(四)call传入了null或undefined

function a() {
  console.log(this);
}
a.call(null);

打印结果:window 对象

根据 ECMAScript262 规范规定:如果第一个参数传入的对象调用者是 null 或者 undefined,call 方法将把全局对象(浏览器上是 window 对象)作为 this 的值。

要注意的是,在严格模式中,null 就是 null,undefined 就是 undefined:

'use strict';

function a() {
    console.log(this);
}
a.call(null); // null
a.call(undefined); // undefined

知识点(五)new出来的this是指向windows的

使用 new 构造函数时,其 this 指向的是全局环境 window。

var obj = { 
  name : 'cuggz', 
  fun : function(){ 
    console.log(this.name); 
  } 
} 
obj.fun()     // cuggz
new obj.fun() // undefined

知识点(五)立即执行函数

  • 立即执行函数是由 window 调用的,this 指向 window
  • 而且在obj里面也会先执行。此时obj.fun1已经变成了立即执行函数里面return出来的函数,所以使用obj.fun1去赋值的时候,db已经变成了所return的那个函数了
function fun() {
  console.log(this); // [object Object] {da: "aa"}
  (function lala(){
    console.log(this === window);// true
  })()
}
fun.call({da:'aa'}) 
// 
window.number = 2;
var obj = {
 number: 3,
 db1: (function(){
   console.log('1',this===window);
   this.number *= 4;
   return function(){
     console.log('4', this===window);
     this.number *= 5;
   }
 })()
}
console.log('2',number);
const db = obj.db1;
console.log('3',number);
db();
console.log('5',number);
// "1" true
// "2" 8
// "3" 8
// "4" true
// "5" 40
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值