使用 Promise

您所在的位置:网站首页 promise如何封装 使用 Promise

使用 Promise

2024-01-16 10:15| 来源: 网络整理| 查看: 265

连续执行两个或者多个异步操作是一个常见的需求,在上一个操作执行成功之后,开始下一个的操作,并带着上一步操作所返回的结果。在旧的回调风格中,这种操作会导致经典的回调地狱:

jsdoSomething(function (result) { doSomethingElse(result, function (newResult) { doThirdThing(newResult, function (finalResult) { console.log(`得到最终结果:${finalResult}`); }, failureCallback); }, failureCallback); }, failureCallback);

有了 Promise,我们就可以通过一个 Promise 链来解决这个问题。这就是 Promise API 的优势,因为回调函数是附加到返回的 Promise 对象上的,而不是传入一个函数中。

见证奇迹的时刻:then() 函数会返回一个和原来不同的新的 Promise:

jsconst promise = doSomething(); const promise2 = promise.then(successCallback, failureCallback);

promise2 不仅表示 doSomething() 函数的完成,也代表了你传入的 successCallback 或者 failureCallback 的完成,这两个函数也可以返回一个 Promise 对象,从而形成另一个异步操作,这样的话,在 promise2 上新增的回调函数会排在这个 Promise 对象的后面。

就像这样,每一个 Promise 都代表了链中另一个异步过程的完成。此外,then 的参数是可选的,catch(failureCallback) 等同于 then(null, failureCallback)——所以如果你的错误处理代码对所有步骤都是一样的,你可以把它附加到链的末尾:

jsdoSomething() .then(function (result) { return doSomethingElse(result); }) .then(function (newResult) { return doThirdThing(newResult); }) .then(function (finalResult) { console.log(`得到最终结果:${finalResult}`); }) .catch(failureCallback);

你或许会看到这种形式的箭头函数:

jsdoSomething() .then((result) => doSomethingElse(result)) .then((newResult) => doThirdThing(newResult)) .then((finalResult) => { console.log(`得到最终结果:${finalResult}`); }) .catch(failureCallback);

注意:一定要有返回值,否则,回调将无法获取上一个 Promise 的结果。(如果使用箭头函数,() => x 比 () => { return x; } 更简洁一些,但后一种保留 return 的写法才支持使用多个语句)。如果上一个处理程序启动了一个 Promise 但并没有返回它,那就没有办法再追踪它的状态了,这个 Promise 就是“漂浮”的。

jsdoSomething() .then((url) => { // 忘记返回了! fetch(url); }) .then((result) => { // 结果是 undefined,因为上一个处理程序没有返回任何东西。 // 无法得知 fetch() 的返回值,不知道它是否成功。 });

如果有竞争条件的话,情况会更糟——如果上一个处理程序的 Promise 没有返回,那么下一个 then 处理程序会提前调用,而它读取的任何值都可能是不完整的。

jsconst listOfIngredients = []; doSomething() .then((url) => { // 忘记返回了! fetch(url) .then((res) => res.json()) .then((data) => { listOfIngredients.push(data); }); }) .then(() => { console.log(listOfIngredients); // 永远是 [],因为 fetch 请求还没有完成。 });

因此,一个经验法则是,每当你的操作遇到一个 Promise,就返回它,并把它的处理推迟到下一个 then 处理程序中。

jsconst listOfIngredients = []; doSomething() .then((url) => fetch(url) .then((res) => res.json()) .then((data) => { listOfIngredients.push(data); }), ) .then(() => { console.log(listOfIngredients); }); // 或 doSomething() .then((url) => fetch(url)) .then((res) => res.json()) .then((data) => { listOfIngredients.push(data); }) .then(() => { console.log(listOfIngredients); });


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3