Promise 输出 合集一

Promise.reject('err!!!')
  .then((res) => {
    console.log('success', res)
  }, (err) => {
    console.log('error', err)
  }).catch(err => {
    console.log('catch', err)
  })
// error err!!!
async function testSometing() {
  console.log("执行testSometing");
  return "testSometing";
}

async function testAsync() {
  console.log("执行testAsync");
  return Promise.resolve("hello async");
}

async function test() {
  console.log("test start...");
  const v1 = await testSometing();
  console.log(v1);
  const v2 = await testAsync();
  console.log(v2);
  console.log(v1, v2);
}

test();

var promise = new Promise(resolve => {
  console.log("promise start...");
  resolve("promise");
});
promise.then(val => console.log(val));

console.log("test end...");

// 'test start...'
// '执行testSometing' 
// 'promise start...' 
// 'test end...' 
// 'testSometing' 
// '执行testAsync' 
// 'promise' 
// 'hello async' 
// 'testSometing' 
// 'hello async'
async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}

async function async2() {
  console.log("async2");
}

console.log("script start");

setTimeout(function() {
  console.log("setTimeout");
}, 0);

async1();

new Promise(function(resolve) {
  console.log("promise1");
  resolve();
}).then(function() {
  console.log("promise2");
});
console.log('script end')

// 'script start' 
// 'async1 start' 
// 'async2' 
// 'promise1' 
// 'script end' 
// 'async1 end' 
// 'promise2' 
// 'setTimeout' 
async function async1 () {
  console.log('async1 start');
  await new Promise(resolve => {
    console.log('promise1')
    resolve('promise resolve')
  })
  console.log('async1 success');
  return 'async1 end'
}
console.log('srcipt start')
async1().then(res => {
  console.log(res)
})
new Promise(resolve => {
  console.log('promise2')
  setTimeout(() => {
    console.log('timer')
  })
})

// srcipt start
// async1 start
// promise1
// promise2
// async1 success
// async1 end
// timer
async function async1 () {
 console.log('async1 start');
 await new Promise(resolve => {
   console.log('promise1')
 })
 console.log('async1 success');
 return 'async1 end'
}
console.log('srcipt start')
async1().then(res => console.log(res))
console.log('srcipt end')


// 结果
// srcipt start
// async1 start
// promise1
// srcipt end

解析
在async1中await后面的Promise是没有返回值的,也就是它的状态始终是pending状态,因此相当于一直在await,await,await却始终没有响应...
所以在await之后的内容是不会执行的,也包括async1后面的 .then。


async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}
async function async2() {
  setTimeout(() => {
    console.log('timer')
  }, 0)
  console.log("async2");
}
async1();
console.log("start")

// async1 start
// async2
// start
// async1 end
// timer
Promise.reject(1)
  .then(res => {
    console.log(res);
    return 2;
  })
  .catch(err => {
    console.log(err);
    return 3
  })
  .then(res => {
    console.log(res);
  });

// 1
// 3

因为reject(1),此时走的是catch,且第二个then中的res得到的就是catch中的返回值。


Promise.resolve(1)
  .then(res => {
    console.log(res);
    return 2;
  })
  .catch(err => {
    return 3;
  })
  .then(res => {
    console.log(res);
  });

// 1
// 2

Promise可以链式调用,不过promise 每次调用 .then 或者 .catch 都会返回一个新的 promise,从而实现了链式调用, 它并不像一般我们任务的链式调用一样return this。
上面的输出结果之所以依次打印出1和2,那是因为resolve(1)之后走的是第一个then方法,并没有走catch里,所以第二个then中的res得到的实际上是第一个then的返回值。
且return 2会被包装成resolve(2)。


const promise = new Promise((resolve, reject) => {
  resolve("success1");
  reject("error");
  resolve("success2");
});
promise
.then(res => {
    console.log("then: ", res);
  }).catch(err => {
    console.log("catch: ", err);
  })


// "then: success1"

构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用 ,Promise的状态一经改变就不能再改变。


Promise.resolve().then(() => {
  console.log('promise1');
  const timer2 = setTimeout(() => {
    console.log('timer2')
  }, 0)
});
const timer1 = setTimeout(() => {
  console.log('timer1')
  Promise.resolve().then(() => {
    console.log('promise2')
  })
}, 0)
console.log('start');

// start
// promise1
// timer1
// promise2
// timer2
  1. 刚开始整个脚本作为第一次宏任务来执行,我们将它标记为宏1,从上至下执行
  2. 遇到Promise.resolve().then这个微任务,将then中的内容加入第一次的微任务队列标记为微1
  3. 遇到定时器timer1,将它加入下一次宏任务的延迟列表,标记为宏2,等待执行(先不管里面是什么内容)
  4. 执行宏1中的同步代码start
  5. 第一次宏任务(宏1)执行完毕,检查第一次的微任务队列(微1),发现有一个promise.then这个微任务需要执行
  6. 执行打印出微1中同步代码promise1,然后发现定时器timer2,将它加入宏2的后面,标记为宏3
  7. 第一次微任务队列(微1)执行完毕,执行第二次宏任务(宏2),首先执行同步代码timer1
  8. 然后遇到了promise2这个微任务,将它加入此次循环的微任务队列,标记为微2
  9. 宏2中没有同步代码可执行了,查找本次循环的微任务队列(微2),发现了promise2,执行它
  10. 第二轮执行完毕,执行宏3,打印出timer2

// 代码一
setTimeout(() => {
  console.log('timer1');
  setTimeout(() => {
    console.log('timer3')
  }, 0)
}, 0)
setTimeout(() => {
  console.log('timer2')
}, 0)
console.log('start')

// 'start'
// 'timer1'
// 'timer2'
// 'timer3'

// 代码二
setTimeout(() => {
  console.log('timer1');
  Promise.resolve().then(() => {
    console.log('promise')
  })
}, 0)
setTimeout(() => {
  console.log('timer2')
}, 0)
console.log('start')
// 'start'
// 'timer1'
// 'promise'
// 'timer2'

这两个例子,看着好像只是把第一个定时器中的内容换了一下而已。
一个是为定时器timer3,一个是为Promise.then
但是如果是定时器timer3的话,它会在timer2后执行,而Promise.then却是在timer2之前执行。
你可以这样理解,Promise.then是微任务,它会被加入到本轮中的微任务列表,而定时器timer3是宏任务,它会被加入到下一轮的宏任务中。


const promise = new Promise((resolve, reject) => {
  console.log(1);
  setTimeout(() => {
    console.log("timerStart");
    resolve("success");
    console.log("timerEnd");
  }, 0);
  console.log(2);
});
promise.then((res) => {
  console.log(res);
});
console.log(4);

// 1
// 2
// 4
// timerStart
// timerEnd
// success
  1. 从上至下,先遇到new Promise,执行该构造函数中的代码1
  2. 然后碰到了定时器,将这个定时器中的函数放到下一个宏任务的延迟队列中等待执行
  3. 执行同步代码2
  4. 跳出promise函数,遇到promise.then,但其状态还是为pending,这里理解为先不执行
  5. 执行同步代码4
  6. 一轮循环过后,进入第二次宏任务,发现延迟队列中有setTimeout定时器,执行它
  7. 首先执行timerStart,然后遇到了resolve,将promise的状态改为resolved且保存结果并将之前的promise.then推入微任务队列
  8. 继续执行同步代码timerEnd
  9. 宏任务全部执行完毕,查找微任务队列,发现promise.then这个微任务,执行它。

console.log('start')
setTimeout(() => {
  console.log('time')
})
Promise.resolve().then(() => {
  console.log('resolve')
})
console.log('end')

// start
// end
// resolve
// time
  1. 刚开始整个脚本作为一个宏任务来执行,对于同步代码直接压入执行栈进行执行,因此先打印出start和end。
  2. setTimout作为一个宏任务被放入宏任务队列(下一个)
  3. Promise.then作为一个微任务被放入微任务队列
  4. 本次宏任务执行完,检查微任务,发现Promise.then,执行它
  5. 接下来进入下一个宏任务,发现setTimeout,执行。

const fn = () =>
  new Promise((resolve, reject) => {
    console.log(1);
    resolve("success");
  });
console.log("start");
fn().then(res => {
  console.log(res);
});

// "start"
// 1
// "success"

start就在1之前打印出来了,因为fn函数是之后执行的。
注意:不要看到new Promise(),就以为执行它的第一个参数函数,我们还需要注意它是不是被包裹在函数当中,如果是的话,只有在函数调用的时候才会执行。


const fn = () => (new Promise((resolve, reject) => {
  console.log(1);
  resolve('success')
}))
fn().then(res => {
  console.log(res)
})
console.log('start')

// 1
// 'start'
// 'success'

fn函数直接返回了一个new Promise的,而且fn函数的调用是在start之前,所以它里面的内容应该会先执行。


const promise = new Promise((resolve, reject) => {
  console.log(1);
  resolve('success')
  console.log(2);
});
promise.then(() => {
  console.log(3);
});
console.log(4);

// 1 2 4 3
  1. 从上至下,先遇到new Promise,执行其中的同步代码1
  2. 再遇到resolve('success'), 将promise的状态改为了resolved并且将值保存下来
  3. 继续执行同步代码2
  4. 跳出promise,往下执行,碰到promise.then这个微任务,将其加入微任务队列
  5. 执行同步代码4
  6. 本轮宏任务全部执行完毕,检查微任务队列,发现promise.then这个微任务且状态为resolved,执行它。

const promise1 = new Promise((resolve, reject) => {
  console.log('promise1')
  resolve('resolve1')
})
const promise2 = promise1.then(res => {
  console.log(res)
})
console.log('1', promise1);
console.log('2', promise2);

// promise1
// '1', Promise{<resolve1>}
// '2', Promise{<pedding>}
// resolve1
  1. 从上至下,先遇到new Promise,执行该构造函数中的代码promise1
  2. 碰到resolve函数, 将promise1的状态改变为resolved, 并将结果保存下来
  3. 碰到promise1.then这个微任务,将它放入微任务队列
  4. promise2是一个新的状态为pending的Promise
  5. 执行同步代码1, 同时打印出promise1的状态是resolved
  6. 执行同步代码2,同时打印出promise2的状态是pending
  7. 宏任务执行完毕,查找微任务队列,发现promise1.then这个微任务且状态为resolved,执行它。

const promise1 = new Promise((resolve, reject) => {
  console.log('promise1')
})
console.log('1', promise1);

// promise1
// '1', Promise{<pedding>}
  1. 从上至下,先遇到new Promise,执行该构造函数中的代码promise1
  2. 然后执行同步代码1,此时promise1没有被resolve或者reject,因此状态还是pending

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容