![](/img/trans.png)
[英]Best way to use javascript promise chaining in order to have truly asynchronous sequence of functions?
[英]Correct way to sequence two asynchronous operations that each return a promise javascript
我想知道在另一个承诺解决之后调用承诺的正确方法是什么。 我知道我们可以使用async await来创建解析promise的函数。 我想知道哪种形式的处理承诺是正确的做法,或者是创建发电机的好习惯? 考虑以下代码:
const fetchSomething = () => new Promise((resolve) => {
setTimeout(() => resolve(console.log('future value')), 500);
});
const fetchSomethingElse = () => new Promise((resolve) => {
setTimeout(() => resolve(console.log('future value dueeee')), 3000);
});
const get = () => {
return fetchSomething().then(function(){
fetchSomethingElse()
});
}
get();
要么
const fetchSomething = () => new Promise((resolve) => {
setTimeout(() => resolve({resolve: true}), 500);
});
const fetchSomethingElse = () => new Promise((resolve) => {
setTimeout(() => resolve({resolve: true}), 3000);
});
const get = async function() {
const fet = await fetchSomething();
const fet2 = await fetchSomethingElse();
};
get();
任何一个都没问题。 你的选择。
在第一个你是嵌套.then()
处理程序。 在第二个中,您使用较新的await
来对它们进行排序。 更多的人正在await
因为它似乎是更简单的排序操作代码(假设你做了正确的错误处理),虽然在这种情况下,它们在复杂性上非常相似,特别是下面建议的简化,所以它真的取决于你自己的个人编码风格。
现在缺少的两个是get()
刚刚返回一个承诺,所以你需要使用.then()
和.catch()
用它获得的价值和捕捉任何错误。
另外,第一个缺少的是你没有返回第二个promise,这意味着调用者不知道第二个操作何时完成。
你的第一个可以简化和修复如下:
const get = () => {
return fetchSomething().then(fetchSomethingElse);
}
get().then(val => {
// done here
}).catch(err => {
// error here
});
正如Pointy所说,你不是“做出承诺”。 你“调用一个返回一个承诺的函数”。 承诺是对象。 他们不可赎回。
你的标题可能被重写的可能是: “正确的方法来排序每个返回一个承诺的两个异步操作” 。
为了完整起见,如果您的两个异步操作不相互依赖,则您不必手动对它们进行排序。 您可以启动它们,然后监视何时完成。 这有时会得到更快的端到端响应。
你可以使用Promise.all()
来做到这Promise.all()
:
const get = function() {
return Promise.all([fetchSomething(), fetchSomethingElse()]).then(results => {
// process results array and then return final value
// results[0] is result from fetchSomething, results[1] is result from fetchSomethingElse
return finalVal;
});
}
两者都很好,但你在顶部的例子中犯了一个常见的错误(也许这只是因为问题代码的简化)。 你从get
回复了诺言,但是你没有从then
回复诺言。 这意味着get
的调用者不知道两个promise何时解决了。 考虑:
const fetchSomething = () => new Promise((resolve) => { setTimeout(() => resolve(console.log('future value')), 500); }); const fetchSomethingElse = () => new Promise((resolve) => { setTimeout(() => resolve(console.log('future value dueeee')), 3000); }); const get = () => { return fetchSomething().then(function(){ fetchSomethingElse() }); } // we don't when fetchSomethingElse is done get().then(() => console.log("done"));
还有另一种选择你可以考虑,因为第二个承诺不依赖于第一个的输出。 并行调用它们:
const get = () => {
return Promise.all([fetchSomething(), fetchSomethingElse() ])
}
在这种情况下,可以在另一个完成之前启动,整个操作应该更快。
重要的是要记住,在基于Promise的模式中,您正在使用返回 Promises的函数。 Promise在resolve
和reject
参数中传递(它们本身就是函数)。 你解决的是,在.then .then()
阶段得到的东西,你拒绝的东西在.catch()
阶段得到了.catch()
。
要按顺序处理Promise,您需要将值传递给包装Promise的顶级函数。
所以...
const p1 = () => { return new Promise((resolve,reject) => { window.setTimeout(() => { resolve('future value one'); },500); }); }; const p2 = (v1) => { return new Promise((resolve,reject) => { window.setTimeout(() => { const v2 = 'future value two'; resolve({v1,v2}); },500); }); }; p1().then(p2).then(console.log);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.