ES6基本的语法(十三) Promise

Promise

Promise 是一个对象,它代表了一个异步操作的最终完成或者失败。因为大多数人仅仅是使用已创建的 Promise 实例对象,所以本教程将首先说明怎样使用 Promise,再说明如何创建 Promise。
本质上 Promise 是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled): 意味着操作成功完成。
  • 已拒绝(rejected): 意味着操作失败。

待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个原因(错误)被拒绝(rejected)。当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序就会被调用,因此在完成异步操作和绑定处理方法之间不会存在竞争状态。

基本使用

// Promise
// 需要传递一个执行期函数 executor function
let Op = new Promise(()=>{

});

Promise 和里面的函数是同步执行

// Promise
// 需要传递一个执行期函数 executor function
let Op = new Promise(()=>{
    // 里面的函数和 Promis 是同步执行
  console.log('0')
});
console.log('1')

// 先打印 0
// 后打印 1

从上面的例子中我们就知道 Promise 和里面的函数是同步执行

异步操作

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
// 使用 setTimeout 模拟异步操作
let op = new Promise((resolve, reject)=>{
    // 异步操作
  setTimeout(()=>{
        Math.random() * 100 > 60 ? resolve("ok"):reject('no')
  },1000)
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
},(err)=>{
    console.log(err); // 输出no
})

在上面的代码中我们使用 setTimeout 来模拟一个异步请求,在 Promise 中有两个参数 resolvereject 分别用来触发成功和失败的回调。

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
let op = new Promise((resolve, reject)=>{
    console.log(0)
  resolve(1);
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
},(err)=>{
    console.log(err);// 输出on
})
console.log(2);

// 输出 0 2 1

是因为 .then 是异步执行,被当成微任务。在上面我们也讲了 resolvereject 分别用来触发成功和失败的回调函数。

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
setTimeout(()=>{
        console.log('setTime');
  },0)
let op = new Promise((resolve, reject)=>{
    console.log(0)
  resolve(1);
});
// 异步执行
//
op.then((val)=>{
    console.log(val); // 输出ok
},(err)=>{
    console.log(err);// 输出on
})
console.log(2);

// 输出 0 2 1 setTime

我们都知道在 JavaScript 的任务队列中分为宏任务和微任务,我们通过 setTimeout() 或者触发事件、时间处理函数、ajax的回调都是放在宏任务。宏任务会被优先放到任务队列(task queue)里面去 ,微任务会被后被放入任务对列之中,但是微任务有优先执行权,所以微任务会优先被执行。

Promise 的链式操作

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
// 使用 setTimeout 模拟异步操作
let op = new Promise((resolve, reject)=>{
    // 异步操作
  setTimeout(()=>{
        Math.random() * 100 > 60 ? resolve("ok"):reject('no')
  },1000)
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
},(err)=>{
    console.log(err); // 输出no
}).then((val)=>{
    console.log("ok then2"+val); // 输出ok
},(err)=>{
    console.log("no then2"+err); // 输出no
})

// 不管前面是输出的 ok 还是 no 都会输出 ok then2 undefined
// 前面的代码不抛出错误, 下面的都会输出 ok then2 undefined

在上面的代码中,不管是成功还是失败,都会输出 ok then2 undefined,除非前面的代码抛出错误

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
// 使用 setTimeout 模拟异步操作
let op = new Promise((resolve, reject)=>{
    // 异步操作
  setTimeout(()=>{
        Math.random() * 100 > 60 ? resolve("ok"):reject('no')
  },1000)
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
  return 20
},(err)=>{
    console.log(err); // 输出no
  return 30
}).then((val)=>{
    console.log("ok then2"+val); // 输出ok
},(err)=>{
    console.log("no then2"+err); // 输出no
})

// 不管前面是输出的 ok 还是 no 都会输出 ok then2 20
// 前面的代码不抛出错误, 下面的都会输出 ok then2 20
// 如果抛出错误,这会输出 ok then2 30

上面的代码中加入了一个 return 20/30 会成为后面链式调用的参数,返回值会成为下一个 then 注册函数的执行参数。

如果返回的是一个 Promise 对象

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
// 使用 setTimeout 模拟异步操作
let op = new Promise((resolve, reject)=>{
    // 异步操作
  setTimeout(()=>{
        Math.random() * 100 > 60 ? resolve("ok"):reject('no')
  },1000)
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
  return new Pormise((resolve,reject)=>{
    resolve('newPromise, ok')/reject('newPromise, no')
  })
},(err)=>{
    console.log(err); // 输出no
  return 30
}).then((val)=>{
    console.log("ok then2"+val); // 输出ok
},(err)=>{
    console.log("no then2"+err); // 输出no
})

// 不管前面是输出的 ok 还是 no 都会输出 ok then2 newPromise, ok

// 如果抛出错误,这会输出 ok then2 newPromise, no

下面的 .then 的执行结果会就根据第一个 .then 的结果去显示对应的内容,成功显示 ok then2 newPromise, ok,失败显示 ok then2 newPromise, no

处理回调地狱

let fs = require('fs');

function readFile(path){
    return new Promise((resolve, reject)=>{
    fs.readFile(path,'utf-8',(err,data)=>{
        if(data){
        resolve(data);
      }
    })
  })
}

readFile(path).then((data)=>{
    return readFile(data);
}).then((data)=>{
    return readFile(data);
}).then((data)=>{
    conosle.log(data);
})

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容

  • ES6 Promise用法讲解 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一...
    为君梳作半面妆阅读 207评论 0 0
  • ES6 Promise 用法讲解 Promise是一个构造函数,自己身上有all、reject、resolve这几...
    Marting424阅读 274评论 1 0
  • Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、c...
    HJHA阅读 285评论 0 0
  • 一、promise的含义 Promise对象有以下两个特点。 (1)对象的状态不受外界影响。Promise对象代表...
    付出的前端路阅读 984评论 0 0
  • 什么叫promise? Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式...
    98b8dc01512b阅读 298评论 0 0