(JS)非常混淆Promise with fetch

时间:2018-01-14 11:49:37

标签: javascript

我已经看过许多关于承诺的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
")

所以主要问题是:

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

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

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

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

    感谢您的时间。

2 个答案:

答案 0 :(得分:3)

您对该抓取代码的评论大多是正确的,只是因为catch位于链的末尾,所以 从原始{ {1}};如果在它之前的fetch回调之一中抛出错误(或从最终拒绝的回复中返回的承诺),它将看到该错误。例如,使用此代码,如果then成功,fetch处理程序将收到catch回调引发的错误:

then

同样,在您引用的代码中,如果fetch(/*...*/) .then(response => throw new Error("fail")) .catch(err => { // Either gets error from `fetch` or failure from `then` above }); 返回的承诺拒绝(无法读取正文,无效的JSON等),您的{{1}处理程序将看到拒绝(错误)。

  

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

不在那段代码中,没有。

  

1。怎么样"新的承诺"?它是什么?我需要它吗?当α

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

  

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

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

  

3。如果我需要"新的承诺",我什么时候解决并拒绝?我该解决/拒绝什么?

当您正在执行的任何非承诺活动完成时,您致电catch。您将活动生成的值(如果有的话)传递给它。

当您执行失败的非承诺活动时,请致电fetch。你传递的内容与resolve使用的内容相同:某种错误。 (通常将其创建为实际错误,例如reject)。

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

答案 1 :(得分:0)

如果要合并fetchresponse.json(),则不必返回new Promise,因为fetch已经是承诺。您只需返回fetch().then(...)

即可

例如

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

如果您想调用接受回调的API并将其转换为承诺,则可以使用new Promise

例如:

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