我是否正确地链接了Promises或犯了罪?

时间:2019-05-15 13:26:40

标签: javascript promise es6-promise

我很久没有使用Javascript了,所以现在promises对我来说是一个新概念。我有一些操作需要个以上的异步调用,但我想将其视为事务,如果之前的步骤失败,则步骤不会执行。目前,我通过嵌套链接承诺,并且我想将承诺返回给呼叫者

在阅读了Mozilla Using Promises指南的链接部分之后,我不确定我在做什么是否正确或等同于“厄运回调金字塔”。

是否有一种更干净的方法(除了在每个HTML中与卫兵检查链在一起)?我是否相信在Mozilla的示例中,即使有错误,它也会执行每个链接的then

then

2 个答案:

答案 0 :(得分:1)

引发异常时,后续的then语句不会执行(直到catch)。另外,.then返回一个Promise,因此您无需创建其他外部Promise。

尝试以下示例:

var p = new Promise((resolve, reject) => {
    console.log('first promise, resolves');
    resolve();
})
.then(() => {
    throw new Error('Something failed');
})
.then(() => {
    console.log('then after the error');
    return('result');
});

p.then(res => console.log('success: ' + res), err => console.log('error: ' + err));

您将不会在控制台中看到“错误后的错误”,因为这是在引发异常之后发生的。但是,如果您评论throw语句,您将在Promise中得到期望的结果。

我不确定我是否完全理解您的示例,但是我认为可以这样简化:

myfunction(key) => {
    return new Promise((resolve, reject) => {
        let item = cache.get(key);
        if (item) {
            resolve(item);
        } else {
            //we didnt have the row cached, load it from store   
            chrome.storage.sync.get(key, function (result) {
                chrome.runtime.lastError
                    ? throw new Error(chrome.runtime.lastError.message)
                    : resolve(result);
            });
        }
    }).then((previousData) => {
        // keyBasedOnPreviousData is calculated based on previousData
        chrome.storage.sync.get(keyBasedOnPreviousData, function (result) {
            chrome.runtime.lastError
                ? throw new Error(chrome.runtime.lastError.message)
                : return result;
        });
    });
}

答案 1 :(得分:1)

有点混乱。这是我的重写尝试。尝试避免的好事是new Promise()

function chromeStorageGet(key) {    
  return new Promise( (res, rej) => {

     chrome.storage.sync.get(key, result => {   
       if (chrome.runtime.lastError) {
         rej(new Error(chrome.runtime.lastError.message))
       } else {
         res(result)
       }
     }); 

  });  
});


function myfunction(key) {

   const item = cache.get(key) ? Promise.resolve(cache.get(key)) : chromeStorageGet(key);
   return item.then( cacheResult => {
     return chromeStorageGet(keyBasedOnPreviousData);
   });

}

为什么要避免使用new Promise()

这样做的原因是您想使用then()做每一步。如果在任何允诺中发生任何错误,则链中的每个允诺都会失败,并且随后的then()都将不被执行,直到{em> 为止,{{1 }}处理程序。

很多基于承诺的代码都不需要错误处理程序,因为基于承诺的函数总是返回承诺,并且异常应该流回调用者,直到对错误处理有用的事情为止。

请注意,这两个规则的例外情况在我的catch()函数中。一些注意事项:

  • chromeStorageGet是将回调代码转换为承诺代码的快速简便的方法。
  • 为基于回调的代码创建一个小的转换层通常是一个好主意。如果您需要在其他地方使用new Promise,则可以创建一个实用程序,使所有功能发挥作用。
  • 如果只有1个“流”,则可以使用一系列chrome.storage.sync完成该过程,但是有时您需要有条件地做其他事情。只需将这些复杂的操作分解为许多不同的功能,就可以真正起到帮助作用。

但这是

then()

几乎总是首选:

const result = condition ? Promise.resolve() : Promise.reject();