创建一个 readFile.js,读取三个文件abc的内容并输出到控制台

var fs = require('fs')
fs.readFile('./a.txt','utf-8',function (err,data) {
if(err)
throw err //js语法,抛出异常,阻止程序执行,把错误打印到控制台
console.log(data) //将a.txt内容输出到控制台
}) fs.readFile('./b.txt','utf-8',function (err,data) {
if(err)
throw err
console.log(data)
}) fs.readFile('./c.txt','utf-8',function (err,data) {
if(err)
throw err
console.log(data)
})

一般来说文件内容少的会先输出,但不一定,由于读取文件是异步操作,所以无法保证abc的输出顺序

若想abc按顺序输出,就需要将代码嵌套

var fs = require('fs')
fs.readFile('./a.txt','utf-8',function (err,data) {
if(err)
throw err
console.log(data) //打印a.txt后再去读取b.txt
fs.readFile('./b.txt','utf-8',function (err,data) {
if(err)
throw err
console.log(data) //打印b.txt后再去读取c.txt
fs.readFile('./c.txt','utf-8',function (err,data) {
if(err)
throw err
console.log(data)
})
})
})

像这样,在异步编程中,形成了回调函数嵌套,嵌套过多时被称为回调地狱(callback hell),此方式虽然能让异步操作按顺序执行,但十分不利于阅读和维护

为了解决回调地狱嵌套编码方式带来的问题,ES6 新增了一个 API 叫 Promise,是一个构造函数

Promise上有两个函数叫resolve(成功后的回调函数)和reject(失败后的回调函数)

Promise原型里有一个then方法,所以只要是Promise创建的实例都可访问then方法

Promise 容器存在一个异步任务,任务只有三种状态:Pending 为正在执行,Resolve 为已解决,Reiected 为失败

示例

var fs = require('fs')
//Promise容器一旦创建就开始执行里面的代码
var p = new Promise(function (resolve,reject) {
  fs.readFile('./a.txt','utf-8',function (err,data) {
  if(err){
  reject(err) //把容器的Pending状态变为Rejected
}else{
resolve(data) //把容器的Pending状态改为Resolve
}
})
}) //如何获取容器成功和失败的数据,就要用到p实例对象的then方法
//then方法接收的第一个function就是容器中的resolved,第二个function是reject
//两个function的参数就是上面容器resolve和reject传来的data和err.若resolve(123),则这里data就是123
p.then(function (data) {
  console.log(data)
},function (err) {
consoel.log('文件读取失败',err)
})

Promise容器的创建不是异步的,但内部往往传入异步任务

封装 Promise 版本的 readFile.js

var fs = require('fs')
function readFile(filePath) {
//将Promise实例对象返回
return new Promise(function (resolve,reject) {
fs.readFile(filePath,'utf-8',function (err,data) {
if(err){
reject(err)
}else{
resolve(data)
}
})
})
} //因为返回的都是Promise的实例对象,所以可链式调用then
readFile('./a.txt')
.then(function (data) {
console.log(data) //data就是上面resolve传来的a文件的内容
//然后将新的数据(err和data)通过resolve和reject传递给下一个then的function
return readFile('./b.txt')
})
.then(function (data) {
console.log(data)
return readFile('./c.txt')
})
.then(function (data) {
console.log(data)
})

封装 Promise 版本的 ajax 方法

function get(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest()
xhr.open('get', url)
xhr.send()
xhr.onload = function () {
resolve(xhr.responseText) //成功则把获取的数据放resolve这个回调函数中
}
xhr.onerror = function (err) {
reject(err) //失败则把失败信息放reject里
}
})
} get('./a.txt')
.then(function (data) {
console.log(data)
return get('./b.txt')
})
.then(function (data) {
console.log(data)
return get('./c.txt')
})
.then(function (data) {
console.log(data)
})

如果前面的promise执行失败,不想让后续的promise操作被终止,可为每个promise指定失败的回调,然后在失败回调里return新的promise

如果后续的promise执行依赖于前面的,前面的失败了,则后面的没有继续执行下去的意义时,可捕获异常

get('./a.txt')
.then(function (data) {
console.log(data)
return get('./b.txt')
})
.then(function (data) {
console.log(data)
return get('./c.txt')
})
.then(function (data) {
console.log(data)
})
.catch(function(err){ //上面不要写失败回调
console.log(err.message)
})

如果前面有任何的promise执行失败则会立即终止所有promise执行并立刻进入catch中

这就是捕获异常的两种方式,根据需求,可选择失败回调或catch

模拟 jQuery 的 get 方法

jq中的ajax()返回的是Promise实例,所以可直接点then()

既能使用 Promise 也可以使用回调函数嵌套的方式,只需加多一个回调函数即可

function get(url,callback) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest()
xhr.open('get', url)
xhr.send()
xhr.onload = function () {
callback(xhr.responseText)
resolve(xhr.responseText) //成功则把获取的数据放resolve这个回调函数中
}
xhr.onerror = function (err) {
callback(err)
reject(err) //失败则把失败信息放reject里
}
})
} /*get('./a.txt')
.then(function (data) {
console.log(data)
return get('./b.txt')
})
.then(function (data) {
console.log(data)
return get('./c.txt')
})
.then(function (data) {
console.log(data)
})*/ get('./a.txt',function (data) {
console.log(data)
get('./b.txt',function (data) {
console.log(data)
get('./c.txt',function (data) {
console.log(data)
})
})
})

浏览器、Node、mongoose所有 API 都支持 Promise

nodejs -Promise的更多相关文章

  1. Nodejs Promise的一点记录

    项目需要,看了点nodejs,其中比较难理解的就是Promise了,记录一下学习bluebird提供的Promise实现. Promise.promisifyAll(obj)方法 作用:把对象的方法属 ...

  2. nodejs promise深度解析

    Promise本质上是一个容器,内部有一个执行函数,当promise对象New出来的时候,内部包裹的函数立即执行. V8引擎会将resolve和projeccted两个函数传递进来,resolved含 ...

  3. 2019前端面试系列——Vue面试题

    Vue 双向绑定原理        mvvm 双向绑定,采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter.getter,在数 ...

  4. vue高频面试题(面试路上踩过的坑)

    ### Vue 双向绑定原理 mvvm 双向绑定,采用**数据劫持结合发布者-订阅者模式**的方式,通过 `Object.defineProperty()` 来劫持各个属性的 setter.gette ...

  5. async异步流程控制

    http://cnodejs.org/topic/54acfbb5ce87bace2444cbfb 先安装:G:\www\nodejs\one\models>npm install async ...

  6. nodejs 回调地狱解决 promise async

    nodejs毁掉地狱是一直被人诟病的,以下总结一下解决毁掉地狱的一些方法.(暂时研究的比较浅) 1.promise promise模式在任何时刻都处于以下三种状态之一:未完成(unfulfilled) ...

  7. queue-fun —— nodejs下基于Promise的队列控制模块。

    工作告一段落,闲来无事,写了一个在nodejs实现“半阻塞”的控制程序. 一直以来,nodejs以单线程非阻塞,高并发的特性而闻名.搞这个“半阻塞”是东西,有什么用呢? 场景一: 现在的web应用可有 ...

  8. 实现nodejs的promises库(基于promise.js改写)

    原promise.js库地址:https://github.com/stackp/promisejs promises是JavaScript实现优雅编程的一个非常不错的轻量级框架.该框架可以让你从杂乱 ...

  9. async/await与promise(nodejs中的异步操作问题)

    此文只是粗略介绍使用方法,欲了解核心概念请参考官方文档或其他资料. 举例写文章详情页面的时候的一个场景:首先更改文章详情中的 PV,然后读取文章详情,然后根据文章详情中文章 Id 查阅该文章评论和该文 ...

随机推荐

  1. day-02(css,js)

    本文档并非个人所写,只是便于参考:回顾: html: 作用:展示 文件标签: <html> <head> <title></title> </he ...

  2. 非root用户ssh 执行 sudo远程机器免密钥

    非root用户ssh 执行 sudo远程机器免密钥 # 1.登陆192.168.1.10 ssh-keygen -t rsa # 一路回车 # 将公钥添加到认证文件中 cat ~/.ssh/id_rs ...

  3. 虚拟机部署hadoop集群准备工作之多虚拟机设置网络信息

    安装好了centos6.4(最简版)后   1,静态IP设置 查看虚拟机的网络设置信息来配置

  4. python mysql安装&&简单基础sql

    ##############总结############## 1.mysql 介绍 Mysql是开源的,所以你不需要支付额外的费用. Mysql支持大型的数据库.可以处理拥有上千万条记录的大型数据库. ...

  5. C#设计模式(9)——代理模式

    1.代理模式介绍 在软件开发中有时会遇到不能直接使用对象的问题,如我们要使用的对象在进程外,甚至在远程的机器上,但是我们要使用这个对象的功能怎么办呢?代理模式就可以用来解决这个问题.举一个生活中的例子 ...

  6. linux 下安装ftp 并远程连接

    1.确认是否已安装 ftp 1 pgrep vsftpd   #查看ftp 服务进程 无结果如下图所示 2.执行安装 1 yum install vsftpd     #安装ftp 服务 3.执行过程 ...

  7. nginx 前端POST请求405问题解决与排查过程

    问题描述 在请求时,f12提示POST请求报错405 环境描述 nginx转发至后端nginx,后端nginx转发至后端golang api接口 解决步骤 根据网上方法排查,发现80%以上无非就是以下 ...

  8. MVC Repository模式

    近来发现很多ASP.NET MVC的例子中都使用了Repository模式,比如Oxite,ScottGu最近发布的免费的ASP.NET MVC教程都使用了该模式.就简单看了下. 在<企业架构模 ...

  9. python初认识、基础数据类型以及 if 流程控制

    python初认识 CPU.内存.硬盘以及操作系统之间的关系 CPU:中央处理器,计算机的逻辑运算单元 硬盘:长期存储数据的地方,断电不会丢失 内存:位于CPU与硬盘之间,缓解高速CPU与低速硬盘之间 ...

  10. 【转载】RPG颜色参考表

    https://blog.csdn.net/a949308398/article/details/17013087