资讯专栏INFORMATION COLUMN

深入理解ES6笔记(十一)Promise与异步编程

RayKr / 1023人阅读

摘要:回调函数模式类似于事件模型,因为异步代码也会在后面的一个时间点才执行如果回调过多,会陷入回调地狱基础可以当做是一个占位符,表示异步操作的执行结果。函数可以返回一个,而不必订阅一个事件或者向函数传递一个回调函数。

主要知识点:Promise生命周期、Promise基本操作、Promise链、响应多个Promise以及集成Promise

《深入理解ES6》笔记 目录
异步编程

JavaScript引擎中,只有一个主线程,当执行JavaScript代码块时,不允许其他代码块执行,而事件机制和回调机制的代码块会被添加到任务队列(或者叫做堆栈)中,当符合某个触发回调或者事件的时候,就会执行该事件或者回调函数。

事件模型

浏览器初次渲染DOM的时候,我们会给一些DOM绑定事件函数,只有当触发了这些DOM事件函数,才会执行他们:

let button = document.getElementById("my-btn");
button.onclick = function(event) {
    console.log("Clicked");
};
回调模式

当 Node.js 被创建时,它通过普及回调函数编程模式提升了异步编程模型。回调函数模式类似于事件模型,因为异步代码也会在后面的一个时间点才执行:

readFile("example.txt", function(err, contents) {
    if (err) {
        throw err;
    }
    console.log(contents);
});
console.log("Hi!");

如果回调过多,会陷入回调地狱;

Promise 基础

Promise可以当做是一个占位符,表示异步操作的执行结果。函数可以返回一个Promise,而不必订阅一个事件或者向函数传递一个回调函数。

// readFile 承诺会在将来某个时间点完成
let promise = readFile("example.txt");

在此代码中, readFile() 实际上并未立即开始读取文件,这将会在稍后发生。此函数反而会返回一个 Promise 对象以表示异步读取操作,因此你可以在将来再操作它。

Promise 的生命周期

Promise的生命周期:进行中(pending),已经完成(fulfilled),拒绝(rejected)
每个 Promise 都会经历一个短暂的生命周期,初始为挂起状态(pending state) ,这表示异步操作尚未结束。一个挂起的 Promise 也被认为是未决的(unsettled )。一旦异步操作结束, Promise就会被认为是已决的(settled ) ,并进入两种可能状态之一:

已完成(fulfilled ) : Promise 的异步操作已成功结束;

已拒绝(rejected ) : Promise 的异步操作未成功结束,可能是一个错误,或由其他原因导致。

内部的[[PromiseState]] 属性会被设置为"pending" 、 "fulfilled" 或 "rejected",以反映Promise的状态。该属性并未在 Promise 对象上被暴露出来,因此你无法以编程方式判断 Promise 到底处于哪种状态。不过你可以使用then()方法在 Promise 的状态改变时执行一些特定操作。

then()

then() 方法在所有的 Promise 上都存在,并且接受两个参数。第一个参数是 Promise 被完成时要调用的函数,与异步操作关联的任何附加数据都会被传入这个完成函数。第二个参数则是 Promise 被拒绝时要调用的函数:

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

catch() 方法

其行为等同于只传递拒绝处理函数给 then()

promise.catch(function(err) {
    // 拒绝
    console.error(err.message);
});
// 等同于:
promise.then(null, function(err) {
    // 拒绝
    console.error(err.message);
});
创建未决的 Promise

Promise 使用 Promise 构造器来创建:

// Node.js 范例
let fs = require("fs");
function readFile(filename) {
    return new Promise(function(resolve, reject) {
        // 触发异步操作
        fs.readFile(filename, { encoding: "utf8" }, function(err, contents) {
            // 检查错误
            if (err) {
                reject(err);
                return;
            }
            // 读取成功
            resolve(contents);
        });
    });
}
let promise = readFile("example.txt");
// 同时监听完成与拒绝
promise.then(function(contents) {
    // 完成
    console.log(contents);
}, function(err) {
    // 拒绝
    console.error(err.message);
});

romise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
执行器会在 readFile() 被调用时立即运行

let promise = new Promise(function(resolve, reject) {
    console.log("Promise");
    resolve();
});
console.log("Hi!");

//输出结果
Promise
Hi!
创建已决的 Promise Promise.resolve()

Promise.resolve()方法接收一个参数,并会返回一个处于已完成状态的 Promise ,在then()方法中使用完成处理函数才能提取该完成态的Promise传递的值,例如:

let promise = Promise.resolve(42);
promise.then(function(value) {
    console.log(value); // 42
});
Promise.reject()

可以使用Promise.reject()方法来创建一个已拒绝状态的Promise,同样只有在拒绝处理函数中或者catch()方法中才能接受reject()方法传递的值:

let promise = Promise.reject(42);
promise.catch(function(value) {
    console.log(value); // 42
});

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97025.html

相关文章

  • 深入理解ES6笔记——导读

    摘要:最近买了深入理解的书籍来看,为什么学习这么久还要买这本书呢主要是看到核心团队成员及的创造者为本书做了序,作为一个粉丝,还是挺看好这本书能给我带来一个新的升华,而且本书的作者也非常厉害。 使用ES6开发已经有1年多了,以前看的是阮一峰老师的ES6教程,也看过MDN文档的ES6语法介绍。 最近买了《深入理解ES6》的书籍来看,为什么学习ES6这么久还要买这本书呢?主要是看到Daniel A...

    Godtoy 评论0 收藏0
  • JavaScript 异步编程的四种方式

    摘要:异步编程是每个使用编程的人都会遇到的问题,无论是前端的请求,或是的各种异步。本文就来总结一下常见的四种处理异步编程的方法。利用一种链式调用的方法来组织异步代码,可以将原来以回调函数形式调用的代码改为链式调用。 异步编程是每个使用 JavaScript 编程的人都会遇到的问题,无论是前端的 ajax 请求,或是 node 的各种异步 API。本文就来总结一下常见的四种处理异步编程的方法。...

    microelec 评论0 收藏0
  • 深入理解ES6笔记—— Promise异步编程(11)

    摘要:为什么要异步编程我们在写前端代码时,经常会对做事件处理操作,比如点击激活焦点失去焦点等再比如我们用请求数据,使用回调函数获取返回值。这些都属于异步编程。回调有多个状态,当响应成功和失败都有不同的回调函数。 为什么要异步编程 我们在写前端代码时,经常会对dom做事件处理操作,比如点击、激活焦点、失去焦点等;再比如我们用ajax请求数据,使用回调函数获取返回值。这些都属于异步编程。 也许你...

    ssshooter 评论0 收藏0

发表评论

0条评论

RayKr

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<