繁体   English   中英

正确的方法来排序每个返回promise javascript的两个异步操作

[英]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在resolvereject参数中传递(它们本身就是函数)。 你解决的是,在.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM