JavaScript 的 Promise、async/await

Promise

创建一个简单的promise对象:

// 创建并执行Promise,传入匿名函数
new Promise( (resolve, reject) => {
  let timeOut = Math.random() * 2;
  log('set timeout to: ' + timeOut + ' seconds.');
  // 1秒后执行判断,小于1输出'成功',否则输出'错误'
  setTimeout(function () {
    if (timeOut < 1) {
      log('call resolve()...');
      resolve('200 OK');
    }
    else {
      log('call reject()...');
      reject('timeout in ' + timeOut + ' seconds.');
    }
  }, timeOut * 1000);
}).then(function(resolve){
  console.log('成功:' + resolve)
}).catch(function(reject){
  console.log('失败:' + reject)
});
// then对应调用resolve回调函数;catch对应调用reject回调函数
// resolve('200 OK')把"200 OK"作为参数传递

 

串联多个promise:

const promise1 = new Promise(fnAsync(){...});
const promise2 = new Promise(fnAsync(){...});
const promise3 = new Promise(fnAsync(){...});
// promise1成功执行后再执行promise2,再是promise3
promise1.then(promise2).then(promise3);

并联多个promise:

const promise1 = new Promise(fnAsync(){...});
const promise2 = new Promise(fnAsync(){...});
const promise3 = new Promise(fnAsync(){...});
// promise1/2/3均成功后再执行then(一个失败也不会执行then)
Promise.all([promise1, promise2, promise3]).then(callback(){...});
// promise1/2/3任意一个成功后执行then
Promise.race([promise1, promise2, promise3]).then(callback(){...})

 

携带特定参数,包裹promise:

const fs = require('fs')
function readFileAsync(path){
  return new Promise((resolve, reject) => {
    fs.readFile(path, (err, data) => {
      if(err) reject(err)
      else resolve(data)
    })
  })
}
// 执行函数
readFileAsync('./test.json')
  .then(data => {
    data = data.JSON.parse(data);
    console.log(data);
})
  .catch(err => {
    console.log(err);
})

 

使用util模块:

const util = require('util')
// 注意传参模式
util.promisify(fs.readFile)('./test.json')
  .then(JSON.parse)
  .then(data => {
    console.log(data.name);
  })
  .catch(err => {
    console.log(err);
  })

 


async/await

 "async" 定义的函数本质是Promise对象(即可以通过 ".catch()" 捕获错误):

async function timeout() {
    return 'hello world'
}
console.log(timeout());
console.log('先执行!');

/* 打印结果:
  先执行!
  Promise { 'hello world' }
*/

 

"await" 表示停在该函数上等待,其结束后再执行之后代码:

// 2s 之后返回双倍的值
function doubleAfter2seconds(num) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(2 * num)
        }, 2000);
    } )
}
// 定义async函数
async function testResult() {
    console.log('---2s后打印resolve---');
    let result = await doubleAfter2seconds(30);
    setTimeout(() => {
        console.log('再过1.5s后打印"await"后语句')
    }, 1500)
    console.log(`result:${result}`);
}
testResult(30);
/* 打印结果:
  ---2s后打印resolve---
  result:60
  再过1.5s后打印"await"后语句
*/

 "await" 与 ".then()" 类似,前者优势是传参方便

一篇不错的async/await博文

阮一峰老师的ES6

 


检验知识

前端一道面试题:

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
promise2
async1 end
setTimeout

理解:

1. js是单线程

2. 分成3个部分:主线程、异步栈、计时器

3. 异步函数内的同步代码(如console.log)会立即执行

4. "await" 和 ".then()" 会阻塞异步对象本身,线程回到主线程

5. "await"后的代码 和 ".then()"内的代码 会被推入"异步栈"中

6. "异步栈"内的代码是"先进后出"

7. 计时器会先"挂起",到达指定时间后"请求"执行,但会被"阻塞",所以总是比设定时间执行稍晚计时器代码

 

 

题目来源此博客

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值