#每日一记# 1分钟学习 Promise 的一例奇妙用法

446 阅读3分钟

每日一记 - 但并不日更

导读

当我们初始化一个 Promise 实例的时候,通常都会在回调函数里设置 Promise 实例状态的变更。

// a.js
const defer = new Promise(resolve => {
	// 模拟异步
	setTimeout(resolve, 3000);
});

export { defer };

 

// b.js
import { defer } from 'a';

defer.then();

这种用法是最常见的写法,可以把一些回调函数给 Promise 化。

从外部变更 Promise 实例状态

这里如果把 Promise 实例的回调入参给保存在全局作用域是不是可以呢?所以看一下这样的代码。

// a.js
let resolve;

const defer = new Promise(_resolve => {
	resolve = _resolve;
});

// 模拟异步
setTimeout(resolve, 3000);

export { defer };

 

// b.js

import { defer } from 'a';

defer.then();

这两种写法的区别就是:resolve 被保存在外部了,对 Promise 实例的操作可以在外部执行了。

这样对 Promise 的初始化(new Promise()),Promise 实例状态变更操作(resolve()),对 Promise 的监听(defer.then()),这三个部分就可以分别写在不同的文件(或者说逻辑片段)中了。

// a.js
let resolve;

const defer = new Promise(_resolve => {
	resolve = _resolve;
});

export { defer, resolve };

 

// b.js

import { defer } from 'a';

defer.then();

 

// c.js

import { resolve } from 'a';

setTimeout(resolve, 3000);

这里只是简单的例子,这个例子的明显缺点是这个 Promise 实例一旦被消费了就没用了。所以可以设计个工厂函数来优化它,这里就不写了。

使用场景

这种写法的使用场景是什么呢?这真的很难举例子,因为它的太不常用了。我唯一使用它的地方是用于关联 http 请求和 websocket 消息。

在 IM 消息系统中,用 http 发送一个 id 为 1 的消息,当服务端处理完毕后会通过 websocket 返回 id 为 1 的消息回执,然后基于回执来更新。

一般这里都会使用设计一个事件系统来处理,来看一下简单的伪代码

// send-msg.js
// 发送 http
const msg = {
	id: 1,
	message: '你好',
}

send(msg)

 

// websocket.js
// 监听 websocket
websocket.on('message', (msg) => {
	update(msg);
})

这里有一个缺点,假如 msg 是一个数据元,那么对这个数据元的操作被分割到了两个文件(或者说逻辑片段)中了。理想中的写法可以如下:

send(msg)
.then(msg => {
	update(msg);
});

那么使用上面 Promise 的方法是可以实现的,具体的情况还会有很多要处理,这里只写一个简单的伪代码例子说明一下。

// send-msg.js
import { defer } from 'a.js';

const msg = {
	id: 1,
	message: '你好',
}

function send(msg) {
	return (
		http(msg)
		.then(() => {
			return defer; // 这里会向外暴露 defer
		})
	)
}

send(msg)
.then(msg => {
	update(msg);
})

 

// websocket.js
import { resolve } from 'a.js';

// 监听 websocket
websocket.on('message', (msg) => {
	resolve(msg);
})

因为 defer(Promise 实例)和其 resolve 方法是关联的,所以这样写就可以把本来分散的逻辑整合起来,写起代码更加流畅。

这里只是提供一个思路,当遇到不好处理的场景时,多一条路走也许能豁然开朗。

装完逼就跑

罗小黑写写文字

如果喜欢文章 请留下一个赞~ 如果喜欢文章 分享给更多人~

掘金中关注我

自由转载-非商用-非衍生-保持署名(创意共享3.0许可证) 转载时请保留原文链接 以保证可及时获取对文章的订正和修改