首页 文章

(JS)非常混淆Promise with fetch

提问于
浏览
1

我已经看到很多关于承诺的youtube视频/课程/“书籍”,但他们没有帮助 . 这只是令人困惑 .

我理解这一点:

fetch("some url/file")   // get "data" from some API and it returns a promise

.then( res => res.json()) // this is a promise but not the raw data that we need

.then(data => console.log(data) // with this I will actually access the actual data

.catch( err => console.log(err) // this is if errors exists but ONLY if It can't open the actual site, like their server is dead or whatever, I know that with an IF statements I can check if the status is 200 and that can work with errors.

我正在阅读更多关于它的信息,并且网站上说“新的Promise()构造函数应仅用于遗留异步任务,例如使用setTimeout或XMLHttpRequest . 使用new关键字创建新的Promise,promise提供解析和拒绝功能提供的回调:“”,然后解决和拒绝怎么样?我甚至需要它们吗?

然后,我在stackoverflow上读到,如果你正在获取,你不需要创建一个“新的Promise”,因为fetch已经返回一个promise(尽管在stackoverflow示例中,这个人就像这样写了一个变量“

function get(url) {

console.log('Making fetch() request to: ' + url);

let promise = new Promise((resolve, reject) => {

fetch(url).then  // etc etc
")

所以主要问题是:

  • “新承诺”怎么样?它是什么?我需要它吗?什么时候?和我谈谈这件事 .

  • 如果我需要“新承诺”,我是否将它放入变量(让test = new Promise)或者我在函数中返回它(函数test(){返回新的Promise})//等等,是什么区别?

  • 如果我需要“新承诺”,我什么时候解决并拒绝?我该解决/拒绝什么?

如果您想通过深入的链接回答这些问题,解释一下,请随意 .

感谢您的时间 .

2 回答

  • 2

    您对该获取代码的评论大多是正确的,除了因为 catch 位于链的末尾,它不仅会收到来自原始 fetch 的失败;如果在它之前的 then 回调之一中抛出了错误(或从最终拒绝的回复中返回的承诺),它将看到该错误 . 例如,使用此代码如果 fetch 成功, catch 处理程序将收到 then 回调引发的错误:

    fetch(/*...*/)
    .then(response => throw new Error("fail"))
    .catch(err => {
        // Either gets error from `fetch` or failure from `then` above
    });
    

    同样,在引用的代码中,如果 response.json() 返回的promise拒绝(无法读取正文,无效的JSON等), catch 处理程序将看到拒绝(错误) .

    ...如何解决和拒绝?我甚至需要它们吗?

    不是那个代码,没有 .

    1.“新承诺”怎么样?它是什么?我需要它吗?什么时候?

    当你没有承诺而你需要一个承诺链时,你需要它 . 当你已经有一个承诺(例如来自 fetch 的那个)并且需要一个承诺链时,你 don't 需要它 .

    2.如果我需要“新承诺”,我是否将它放入变量(让test = new Promise)或者我在函数中返回它(函数test())//等等,有区别吗?

    在这方面,承诺没有什么特别之处 . 如果您需要稍后在同一范围内引用它,请使用变量 . 如果没有,您可以直接返回(如果返回) .

    3.如果我需要“新承诺”,我什么时候解决并拒绝?我该解决/拒绝什么?

    当你正在做的任何非承诺活动完成时,你调用 resolve . 您传递活动生成的值(如果有) .

    当你正在做的任何非承诺活动失败时,你调用 reject . 你传递它与 throw 使用的相同:某种错误 . (通常通过将其创建为实际错误,例如 new Error(...) ) .

    更多阅读 new PromiseWhat is the explicit promise construction antipattern and how do I avoid it?

  • 0

    如果你想组合 fetchresponse.json() ,你不必返回 new Promise ,因为 fetch 已经是一个承诺 . 你可以退回 fetch().then(...)

    例如

    const fetchJson = url =>
      fetch(url).then(r=>g.json());
    

    如果要调用接受回调的API并将其转换为promise,则可以使用 new Promise .

    例如:

    const classicApiToPromise = arg =>
      new Promise(
        (resolve,reject)=>
          classicApi(
            arg,
            (data,err)=>//classic callback
              (err)
                ? reject(err)
                : resolve(data)
          )
      );
    

相关问题