前言
一直都想写关于Promise的东西,Promise解决的问题特别多,而普通前端就把这东西结合ajax来做一个await request()
,如果仅仅作为这样一种东西使用那就太可惜了。
它是队列的任务包
前端同学应该是没听说过队列,但是大前端同学,例如搞安卓的或者IOS的肯定听过,在安卓开发种,所有的UI操作都需要给主进程处理,这里的new Runnable() 就很像Promise
安卓里面的线程子类
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
handler = new Handler(Looper.getMainLooper());
// 启动一个子线程
new Thread(new Runnable() {
@Override
public void run() {
// 模拟一些后台工作
try {
Thread.sleep(2000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
// 更新UI,必须在主线程中进行
handler.post(new Runnable() {
@Override
public void run() {
textView.setText("更新后的文本");
}
});
}
}).start();
}
}
Python 协程中的Future
import asyncio
def async_task(future, success=True):
async def task():
await asyncio.sleep(2)
if success:
future.set_result("Task completed successfully")
else:
future.set_exception(ValueError("Something went wrong"))
return task()
def success_callback(result):
print(f"Success: {result}")
def error_callback(error):
print(f"Error: {error}")
async def main():
future = asyncio.Future()
# 启动异步任务
asyncio.create_task(async_task(future))
# 注册成功和错误回调
future.add_done_callback(lambda f: success_callback(f.result()) if not f.exception() else error_callback(f.exception()))
# 等待 Future 完成
await future
# 运行事件循环
asyncio.run(main())
Promise 的异步转同步操作
function updateDomElement(element, newValue) {
return new Promise((resolve, reject) => {
// 假设这里是一个异步的DOM更新操作
element.textContent = newValue;
// 模拟DOM更新完毕,触发一个自定义事件
const event = new Event('domUpdated');
setTimeout(() => {
element.dispatchEvent(event);
}, 1000); // 1秒后触发更新完成事件
// 监听自定义事件,表示DOM更新完毕
element.addEventListener('domUpdated', function onDomUpdated() {
element.removeEventListener('domUpdated', onDomUpdated);
resolve(true); // 触发Promise的resolve
});
// 如果有可能的错误情况,也可以调用reject(error)
});
}
// 使用示例
async function performOperation() {
const element = document.getElementById('myElement');
// 更新DOM元素,并等待更新完成
await updateDomElement(element, "New Content");
// DOM更新完成后继续操作
console.log("DOM updated successfully. Now performing next operations...");
// 继续后续操作
}
performOperation();
创建一个Promise,直到有人调用了这个Promise.resolve()函数
只要你理解了上面任务包的概念之后,并且你知道只要有人调用了Promise.resolve()这个函数后,这个任务包就处理成功了,那么只要你创建了它,就相当于塞到了事件循环队列里去了。
await就是一个生产者,同时还把它下面的代码都自动封装成了回调函数,之后的就没有自己的故事了。
async 相当于一个消费者,负责等待任务逻辑调用这个Promise.resolve()函数,一旦有逻辑调用了Promise.resolve函数,就意味着这个Promise任务被处理完毕了,就可以开始它的后续回调了。
Promise都有哪些用途?
-
你试试用promise将websocket封装为一个await wsrequest(),这样能让你像调用http一样调用websocket,非常方便,怎么搞?
-
https://blog.csdn.net/wangsenling/article/details/130224796https://blog.csdn.net/wangsenling/article/details/130224796
-
插件与网页的异步通信,上面已有演示,通过事件的方式,来回倒腾,实现同步请求
-
谷歌插件inject注入脚本与content script基于Promise+async/await 同步通信实现过程_chrome plugin inject-CSDN博客文章浏览阅读1.1k次。因为webpage和contentscript是两个隔离环境,在webpage(普通网页)中有CSP安全机制,而在macm1环境,MV3版本下无法修改response.header这个bug半年前反馈给谷歌,后续也没见结果,所以,想在webpage网页中直接请求远程url是走不通的,只有借助contentscript来协助请求数据,但是这里牵涉到两个步骤,能否实现异步转同步方式来处理这个过程?_chrome plugin injecthttps://blog.csdn.net/wangsenling/article/details/129918148
-
网页UI的动画或者状态变化的后续操作,demo省略
-
Electron中各种复杂调度下的异步转同步操作
总之把Promise运用在异步转同步的构建上,才能发挥出Promise存在的意义,可以理解为一切异步操作都可以用Promise来封装,实现完美的调度逻辑。