深入理解ES6 011【学习笔记】

Promise与异步编程

因为执行引擎是单线程的,所以需要跟踪即将运行的代码,那些代码被放在一个任务队列中,每当一段代码准备执行时,都会被添加到任务队列中,每当引擎中的一段代码结束执行,事件循环会执行队列中的一下个任务。

Promise相当于异步操作结果占位符,它不会去订阅一个事件,也不会传递一个回调函数给目标函数,而是让函数返回一个Promise,就像这样

// readFile承诺在未来的某个刻完成
let promise = readFile('txx.txt')

Promise的生命周期

  • pending
  • fulfilled 成功
  • rejected 程序错误或一些其他原因

[[PromiseState]]内部属性被用来表示Promise的3种状态,这个属性不暴露在Promise对象上,所以不能以编程的方式检测Promise的状态,只有当Promise状态改变时,通过then()方法来采取特定的行为。所以Promise都有then方法,它接受两个参数,fulfilled和rejected时的两个回调函数

如果一个对象实现了上述的then方法,那这个对象我们就称之为thenable对象,所有的Promise对象都是thenable对象,但并非所有thenable对象都是Promise。

let promise = readFile("example.txt");
promise.then(function(contents){
  // 完成
},function(err){
  // 拒绝
})
promise.then(function(contents){
  // 完成
})

promise.then(null,function(err){
  // 拒绝
})
// catch等同于上面这种
promise.catch(function(err){
  // 拒绝
})

如果向Promise.resolve()方法或Promise.reject()方法传入一个Promise,那么这个Promise会被直接返回

Nodejs环境的拒绝处理

  • unhandledRejection
  • rejectionHandled
let rejected;
process.on("unhandledRejection",function(reason,promise){
  console.log(reason.message); // "Explosin"
  console.log(rejected === promise); // "Explosin"
})
rejected = Promise.reject(new Error('Explosin'))

串联Promise及链式返回值

let p1 = new Promise(function(resolve,reject){
  resolve(42)
})
p1.then(function(value){
  console.log(value)
  return value+1;
})
.then(function(value){
  console.log(value); // "43"
})

let p1 = new Promise(function(resolve,reject){
  reject(42)
})
p1.catch(function(value){
  console.log(value) // 42
  return value+1;
})
.then(function(value){
  console.log(value); // "43"
})

在Promsie链返回Promise

Promise.all()

只接受一个参数并返回一个Promise,该参数是一个含有多个受监视Promise的可迭代对象,只有当可迭代对象中所有Promise都被解决后返回的Promise才会被解决,只有当可迭代对象中所有Promise都完成后返回的promise才会被完成。只要有一个reject,就不用等所有的都完成就会被reject。

let p1 = new Promise(function(resolve,reject){
  resolve(42)
})
let p2 = new Promise(function(resolve,reject){
  reject(43)
})
let p3 = new Promise(function(resolve,reject){
  resolve(44)
})
let p4 =  Promise.all([p1,p2,p3])
p4.catch(function(value){
  console.log(Array.isArray(value)); //false
  console.log(value); // 43
})

Promise.race()

只要有一个resolve,不用等所有的都被完成。一旦数组中的某个Promise被完成,Promise.race()方法也会像Promise.all()方法一样返回一个特定的Promise

Promise继承

class MyPromise extends Promise {
  // 使用默认的构造函数

  success(resolove,reject){
    return this.then(resolove,reject)
  }
  failure(reject){
    return this.catch(reject)
  }
}
let promise = new MyPromise(function(resolve,reject){
  resolve(42)
})
promise.success(function(value){
  console.log(value) // 42
})
.failure(function(value){
  console.log(value)
})

基于Promise的异步任务执行

改造之前的文件读取功能。只要每个异步操作都返回Promise,就可以极大地简化并能用化这个过程。以Promise作为通用接口用于所有异步代码可以简化任务执行器。

let fs = require("fs");

function run(taskDef){
  // 创建迭代器
  let task = taskDef()

  // 开始执行任务
  let result = task.next();

  // 递归函数遍历
  (function step(){
    // 如果有更多任务要做
    if(!result.done){
      // 用一个Promise来解决会简化问题
      let promise = Promise.resolove(result.value);
      promise.then(function(value){
        result = task.next(value);
        step()
      })
      .catch(function(error){
        result = task.throw(error);
        step();
      })
    }

  }())
}
// 定义一个可用于任务执行器的函数
function readFile(filename){
  return new Promise(function(resolove,reject){
    fs.readFile(filename,function(err,contents){
      if(err){
        reject(err);
      } else {
        resolove(contents)
      }
    })
  })
}

// 执行一个任务
run(function *(){
  let contents = yield readFile("config.json");
  doSomethingWith(contents);
  console.log("Done")
})

主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/4337

(0)
Walker的头像Walker
上一篇 2025年3月8日 13:04
下一篇 2025年3月8日 12:52

相关推荐

  • 深入理解ES6 008【学习笔记】

    迭代器(Iterator)和生成器(Generator) 这个新特性对于高效的数据处理而言是不可或缺的,你也会发现在语言的其他特性中也都有迭代器的身影:新的for-of循环、展开运算符(...)、甚至连异步编程都可以使用迭代器。 迭代器是一种特殊的对象,它具有一些专门为迭代过程设计的专有接口,所有的迭代器对象都有一个next()方法,每次调用都返回一个结果对…

    个人 2025年3月8日
    1.1K00
  • Node深入浅出(圣思园教育) 001【学习笔记】

    node 从异步编程范式理解 Node.js Node.js 的定位与核心思想 基于 V8 引擎 + libuv 事件驱动库,将 JavaScript 从浏览器带到服务器侧。 采用单线程事件循环处理 I/O,最大化利用 CPU 等待 I/O 的时间片,特别适合高并发、I/O 密集型场景。 “不要阻塞主线程”是设计哲学:尽量把耗时操作交给内核或线程池,回调结果…

    个人 2025年11月24日
    28100
  • TS珠峰 001【学习笔记】

    课程大纲 搭建 TypeScript 开发环境。 掌握 TypeScript 的基础类型,联合类型和交叉类型。 详细类型断言的作用和用法。 掌握 TypeScript 中函数、类的类型声明方式。 掌握类型别名、接口的作用和定义。 掌握泛型的应用场景,熟练应用泛型。 灵活运用条件类型、映射类型与内置类型。 创建和使用自定义类型。 理解命名空间、模块的概念已经使…

    个人 2025年3月27日
    1.5K00
  • TS珠峰 002【学习笔记】

    泛型 /* * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git &a…

    个人 2025年3月27日
    1.5K00
  • 无畏前行,拳释力量 🥊💪

    拼搏,是一种态度 生活就像一场比赛,没有捷径可走,只有不断训练、突破、超越,才能站上属于自己的舞台。这不仅是一种对抗,更是一种自我的觉醒——敢于迎战,敢于挑战,敢于成为更强的自己。 运动中的拼搏精神 无论是拳击、跑步,还是力量训练,每一次出拳、每一次挥汗、每一次咬牙坚持,都是对身体与心灵的磨炼。拼搏不是单纯的对抗,而是一种态度——面对挑战,不退缩;面对失败,…

    个人 2025年2月26日
    1.3K00
简体中文 繁體中文 English
欢迎🌹 Coding never stops, keep learning! 💡💻 光临🌹