惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
小众软件
小众软件
The Cloudflare Blog
S
SegmentFault 最新的问题
美团技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
阮一峰的网络日志
阮一峰的网络日志
博客园 - 聂微东
V
Visual Studio Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
WordPress大学
WordPress大学
T
Tailwind CSS Blog
腾讯CDC
人人都是产品经理
人人都是产品经理
月光博客
月光博客
Microsoft Azure Blog
Microsoft Azure Blog
M
MIT News - Artificial intelligence
D
DataBreaches.Net
Apple Machine Learning Research
Apple Machine Learning Research
P
Proofpoint News Feed
J
Java Code Geeks
宝玉的分享
宝玉的分享

晚花行乐

马克卡尼在2026年达沃斯论坛上的讲话(阅读材料) | 晚花行乐 鸡娃如何用力才是恰到好处 | 晚花行乐 读万卷书,行万里路的辩证关系 | 晚花行乐 反对培训机构掐尖招生 | 晚花行乐 小泽和建国会谈最后10分钟全文(阅读材料) | 晚花行乐 来看看 DeepSeek 怎么鸡娃 | 晚花行乐 谈谈基本功 | 晚花行乐 惠普 ProDesk SFF PC 各系列参数对比 | 晚花行乐 解决瘦客户机上安装 Debian 12 启动失败问题 | 晚花行乐 意拾喻言:老外写的文言文 | 晚花行乐 笠翁对韵中的典故(十三元) | 晚花行乐 谈谈中考取消四小门 | 晚花行乐 亚马逊云科技产品免费试用攻略(3) - 对象存储服务 | 晚花行乐 在 Windows 10 LTSC 版本上安装 WSL2 | 晚花行乐 Debian 12 的常用配置项 | 晚花行乐 在 Debian 12 上安装 Nvidia 显卡驱动程序 | 晚花行乐 解决 Debian 12 关机失败问题 | 晚花行乐 解决 VS Code 自动更新版本后卡在连接界面 | 晚花行乐 观看巴黎奥运会有感 | 晚花行乐 在 Windows10 上安装惠普旧打印机驱动程序 | 晚花行乐 欢迎关注公众号:晚花行乐 | 晚花行乐 如何编写拼写检查器 | 晚花行乐 亚马逊云科技产品免费试用攻略(2) - 云服务器 | 晚花行乐 Pandas 中 axis 参数的理解(附实例) | 晚花行乐 我打算命个名,叫什么什么 Manager | 晚花行乐 上海武康路历史建筑一览 | 晚花行乐 Python 实现简单的数学表达式解析并处理 | 晚花行乐 观看马拉松的感悟 | 晚花行乐 Python 保存 Cookies 到文件并再次读取 | 晚花行乐 如何为 Hugo 静态网站添加评论功能 | 晚花行乐
Promise 概念的理解 | 晚花行乐
2019-04-17 · via 晚花行乐

在 《Puppteer 实现 web 自动测试》 一文里,可以看出来如果 Puppteer 脚本用 async/await 和 promise的一些写法,会让脚本非常易懂,而且符合我们人工操作浏览器的习惯。所以为了写好 Puppteer 脚本,需要先对 async/await 的概念有所了解。

一个比方

你和老王打赌:明天是否下雨。如果你赢了,老王给你10个亿;如果你输了,你给老王10块钱。


如果用一块展板描述这个赌局,可以是这样:

【明日下雨】 老王赌局
——————————
赢: +10亿
输: –10元

转眼跟小王打赌:

【明日下雨】 小王赌局
——————————
赢: 被请KFC
输: 请KFC

由上可见, 赌局 和 赌注 是无关的。比如,同样是明天下雨,另一场赌局可能如下:

由此得到【规则1】

  • 规则1:输赢规则和赌注无关,可以分离

当赌局完成后,只要出现了一种情况,那么另一种情况必然不会同时发生,比如不可能既下雨又不下雨。由此得到【规则2】

  • 规则2:只能有一种结果出现。

如果你和老王商量好了:如果明天下雨,老王付你10块钱。到了第二天果然下雨,老王反悔了,想修改输赢规则,你一定是不同意的,这就叫买定离手。由此得到【规则3】

  • 规则3:输赢结果一旦出现,则不能更改。

如何描述

用一段伪代码描述上面的下雨赌局,可以这么写

赌局(赢,输){
    到明天()
    如果下雨{
        赢()
    }如果没下{
        输()
    }
}

到明天 函数可以替换成 抛硬币(), 或者是 参加考试(),这种负责产生结果的函数,可以称之为"生产者"。

赢 函数 可以是 {得5元} ,或者是 {被请KFC},这种针对结果的处理方案,可以称之为"消费者"。

这种"生产者"和"消费者"分离的状态,对应了上面的 规则 1

而赌局本身,既不产生结果,也不消费结果,只是将无关的二者结合在一起,并进行一次。将赌局抽象出来,就是 Promise 。

生产者(抛硬币)→ Promise → 消费者(赌注)

所以 Promise 可以理解为一个中介(Proxy),一个 Promise 对象用下面代码生成:

let promise = new Promise(function(resolve, reject) {
  // 生产者代码
});

promise 对象生成时,将执行 生产者代码,并生产出结果。Promise 接收一个函数作为参数,这个函数的两个参数分别对应成功和失败的消费者函数,消费前面生产出的结果。

生产者代码在得出结果后,应该根据结果的不同,调用对应的消费者函数(成功则调用 resolve,失败则调用 reject),同时将结果作为消费者函数的参数,从 promise 对象中传递出去。

举个例子,最简单的生产者代码,恐怕就是"什么也不做"了,直接判定为成功,只有resolve一种结果。

let promise = new Promise(function(resolve, reject) {
  resolve("done")
});

这段代码执行后,对象 promise 的状态就固定为成功(fulfilled),而且不能改变。当然也可以直接判定失败:

let promise = new Promise(function(resolve, reject) {
  reject("lose")
});

这段代码执行后,对象 promise的状态就固定为失败(rejected)

Await

生产者代码除了生产成功或者失败的结果,往往还有其他类型的结果输出,比如文件内容、或者新的对象实例,等等。所以需要通过 resolve 函数将输出的结果传递出来。 await 可以在外面接纳这个结果。

Promise → resolve → await

比如,可以这么使用 await

let promise = new Promise(function(resolve, reject) {
  resolve("done")
});

  let result = await promise; 

  console.log(result);  // "done"

这个例子里,我们可以从控制台里看到 “done” 的输出, await 一直等待 promise 的成功结果,一旦等到,就将 resolve 的参数返回给 result 变量

Async

要想使用 await 关键字,还必须声明 await 所在的函数为 async,用法很简单,只要在 function 前面加上 async 就行。

async function(){ await … }

async function(){
  let promise = new Promise(function(resolve, reject) {
    resolve("done")
  });

  let result = await promise; 

  console.log(result);  // "done"
}

函数声明之前加上 async 后, 即使不用明确的声明 return,函数总会隐含的返回一个 Promise。如果明确的写明 return 一个值,函数也仍然返回一个 Promise,然后使这个 Promise 成功 resolve 那个值。比如下面的例子:

async function(){
  //其他代码

  return 1
}

等效于

async function(){
  //其他代码

  return Promise.resolve(1)
}

这个返回值是可以被 await 等待得到的。

理解了上面的内容,我们就可以继续用 puppeteer 编写自动脚本了

各位读后有什么想法,请在下方留言吧!如果对本文有疑问或者寻求合作,欢迎 联系邮箱邮箱已到剪贴板

精彩评论