困扰了很久的异步问题 一般来说,想要 JS 程序顺序执行,会借助 Promise 的链式结构来顺序调用程序
new Promise(resolve => {
Afunc();
resolve(any);
}).then( res=>{
Bfunc();
})
现在我想要做更复杂一点的事,例如 Afunc 里是 react 组件里的一个发请求并 setState 的函数
Afunc = () =>{
axios.post(`xxx`,{params}).then(res=>{
if(res.xxxx === 'xxxx'){
this.setState({},callBackFunc);
}
})
}
我有一些业务函数(操纵 UI,脏代码)要在 setState 之后才做,也就是塞在 callBackFunc 里 显然
new Promise(resolve=>{
Afunc();
resolve // resolve 之后不知道多少个 then 才执行 Afunc 里的 .then(res=>{...})
})
不满足我新产生的想法。因为 resolve 的时候 Afunc 只跑到 post, .then 里的代码还没轮到 那么我的问题是,如何在不往 Afunc 里塞 callback 的实现一个可以操控的事件流 我现在的做法
Afunc = (callback) =>{
...
this.setState({},()=>{
callback && callback();
})
}
《 You don't know JS 》里看到的好像是 setTimeout 和 promise 混用的时候,把 resolve 给塞到 setTimeout 中的函数 promise((solve)=>{setTimeout(()=>{func, resolve},1000)}
P.S.(如果要手动实现事件队列那还是算了)
P.S. async/await generator 这些也基于 Promise 的语法糖,真的会有用吗?
1
AlphaTr Feb 27, 2020 via iPhone 把 Afunc 包装成 promise
|
2
maichael Feb 27, 2020 大概能这么干,但我没有实测。
Afunc = async () => { const res = await axios.post(`xxx`, {params}) if(res.xxxx === 'xxxx') { retrun new Promise(resolve => this.setState({}, resolve)) } } 用的时候直接 await Afunc() otherFunc() 或者 Afunc().then() |
3
crysislinux Feb 27, 2020 2 楼的办法就可以了
|
4
kof21411 Feb 27, 2020 2 楼方法正确,async/await 异步变同步
|
6
aaronlam Feb 27, 2020
我现在在项目里基本上用 async await 就能解决很多异步顺序执行的问题
|
7
love Feb 27, 2020
async/await 直观多了,虽然可以做的事回调和 promise 都能做
|
8
TheCZ Feb 27, 2020
这个帖子需要 马克一下 最近遇到同样的疑惑!
|
9
ethusdt Feb 27, 2020 @azcvcza #5 「我有一些业务函数(操纵 UI,脏代码)要在 setState 之后才做,也就是塞在 callBackFunc 里」显然就需要在 setState({}, callback) 塞回掉了,避免不了的。
所以你的问题答案是: return new Promise(r => this.setState({}, r)) |
10
mmdsun Feb 27, 2020 via Android async/await 可以看一下 msdn 异步文档。async/await 和 Rx 系列,最早都是微软搞出来模型。官方文档很全面。
然后对比学习 coroutine stackful。js 的 async/await 和 fibjs,还有 c#的 async/await,go 的 goroutine。这样异步就不会有什么问题了。 |
12
azcvcza OP @mmdsun 实际上 js 里的 async/await 是包了一层 promise 在里边,我其实真正想知道的是,除了 async/await,和 promise 这系列的顺序流操纵之外,除了往函数参数里塞回调,是不是还会有其他一些通用的,确定异步函数完成时机的东西。当然我自己翻 js 高程,you don‘t know js 没找到这么细的,you don't know 里提到最接近的就是 promise 里塞一个 setTimeout,在 setTimeout 里 resolve 了。生成器看是看了,但平常用的太少
|
14
duan602728596 Feb 28, 2020
class Com extends React.Component {
state = { data: [] }; changeData(data) { return new Promise((resolve, reject) => { this.setState({ data }, resolve); }); } async getData() { const res = await fetch(url); const data = await res.data.json(); await this.changeData(data); // 之后要做的事情 } componentDidMount() { this.getData(); } } 根据你的意思写的模拟的代码,就这个意思? |
15
StrayBugs Feb 28, 2020 via Android
你想的方向不对
> 我有一些业务函数(操纵 UI,脏代码)要在 setState 之后才做 react 何时应用更新 states 是不可知的,那么这些副作用应该放到生命周期或者 effect hooks 中处理。 |
16
StrayBugs Feb 28, 2020 via Android
好吧,才发现 setState callback 也是安全的,这么用得比较少,补了个盲点。那么 2 楼是正解。
|
18
azcvcza OP @duan602728596 差不多是这样,你的拆分看起来合适,但本质上还是往里边塞回调了
|