答应我 return 使用回调时的待处理状态

promise me return a pending state when I use a callback

我用回调测试了提取 API,但是我的函数 returns “Promise State: Pending”,我不明白为什么 :

async function getJson(url, callback) {
  await fetch(url)
    .then(async function(response) {
      return await response.json()
    })
    .then(function(data) {
      console.log(data)
      callback(data)
    })
}

let getData = {
  getAll: async function() {
    await getJson('js/getJson/data.json', function(data) {
      console.log(data.photographers) //OK
      let test = data.photographers
      return test

    })
  }
}

console.log(getData.getAll()); //return promise pending

谢谢

下面列出的异步和基于承诺的编程的一般建议...

getJson() 应该是这样的:

function getJson(url, callback) {
  return fetch(url).then(function(response) {
      return response.json();
  });
}

只是 return fetch() 已经 return 的承诺 - 不要尝试转换为回调。将基于承诺的接口转换为回调接口在编程可用性方面是倒退的。对于异步编程,Promises 比简单的回调更好用。

下面是 getAll() 如何使用它:

const getData = {
  getAll: async function() {
    const data = await getJson('js/getJson/data.json');
    return data.photographers;
  }
}

或者,同样好的(相当于上面的例子)是这样的:

const getData = {
  getAll: function() {
    return getJson('js/getJson/data.json').then(data => {
        return data.photographers;
    });
  }
}
当您对多个异步操作进行排序时,

await 具有显着优势,但当只有一个异步操作时通常并没有太大帮助。那样用也没有错,只是帮不上什么大忙。

而且,下面是 getAll() 的调用方式:

getData.getAll().then(photographers => {
    console.log(photographers);
}).catch(err => {
    console.log(err);
});

一般建议和解释:

1.阅读并研究 asyncawait 如何使用 promises。 只有在你理解后才使用它,然后你将只在等待 promise 时使用 awaitawait 除非您正在等待一个承诺,否则不会做任何有用的事情,所以如果您正在等待一个函数调用,那么该函数必须 returning 一个承诺,并且该承诺必须连接到其中的异步操作功能完成。

2。不要混合普通回调和 promises。 如果您使用 promise 接口进行编程,请使用该 promise - 永远不要将其转换为普通回调。 Return 来自您函数的承诺,让调用者使用它。发明 promise 的众多原因之一是非简单异步操作中的控制流通过 promises 变得非常简单(特别是异步错误处理和错误传播到更高级别)。

3。 Convert plain callbacks to promises. 如果你遇到一个异步操作,你想在一个有其他基于 promise 的异步操作(例如 fetch())的世界中使用,那么将普通回调包装成一个 promise 接口,所以你只是将基于 promise 的调用与其他基于 promise 的调用混合在一起。可靠地编写代码要简单得多。

4. async 总是return 一个承诺。 这就是它们在 Javascript 内部构建的方式。因此,async 函数的调用者总是会返回一个作为 return 值的承诺。该承诺最初将处于 pending 状态。它将在未来的某个时候得到解决,并且承诺的最终解决值将是 return 从 async 函数的外部范围编辑的任何值。如果在 async 函数的外部范围内没有 return 语句,那么解析的值将是 undefined ,因为它与你的两个 `async 函数一样。

5.调用者使用 .then()await. 从承诺中获取解析值。这是从承诺中获取解析值的仅有的两种方法。因此,async 函数的任何调用者想要从它返回一些值需要使用 .then()await 来获取该值。

6.如果你在一个函数中有一个基于 promise 的操作并且你希望 return 它是你函数的解析值,那么只需 return 来自函数的 promise。 这将允许调用者使用该承诺来获得价值。请参阅我上面的 getJson() 实现,了解它有多简单。

7.避免使用 return await fn() 并改用 return fn() 如果您正在使用 return await fn(),那么您已经在 async 函数中,因此该函数已经return许下诺言。因此,避免使用额外的 await,因为它没有任何用处,只需使用 return fn()。如果 fn() return 是一个值,该值将成为您的 async 函数 returned 的承诺的解析值。如果 fn() return 是一个承诺,那么该承诺的解析值将成为您的 async 函数 returned.

的承诺的解析值

8. Return从 .then() 处理程序中获取一个值成为父 promise 的已解析值。 在上面的第二个 getData() 示例中,内部使用 .then()return data.photographers; 语句将父 promise 的解析值设置为 data.photographers。因此,getData() 的任何调用者都会发现 data.photographers 成为 getData() returns.

承诺的解析值

9. Return来自 .then() 处理程序的承诺将承诺和承诺的解析值链接起来 return 成为父承诺的解析值。 本质上,return 来自 .then() 的承诺导致父级承诺等待新的 returned 承诺解决,然后它从新的 returned 承诺中获取其已解决的值。您可以在 getJson() 函数中看到这一点,其中 response.json() return 是一个解析为 http 请求的 json 解析主体的新承诺。该解析值将成为函数 returned.

承诺的解析值

10。不要在期望返回承诺时传递回调。 如果您将回调传递给某个异步函数,那么大多数时候该函数不会 returning 承诺,因为许多异步这些天的 API 接受回调或 return 承诺,但不要同时进行。因此,在考虑使用 await 时,请绝对确保您正在等待的功能是 return 承诺。如有疑问,请查看文档。如果文档不清楚,请查看函数本身的代码或 运行 进行实验以查看 return 值实际是什么。例如,如果您不向它们传递回调,大多数 mongodb 异步 API 将 return 承诺,但如果您传递回调,则不会 return 承诺。使用一个或另一个,而不是两个。

它有效,虽然它不是我真正想要的。因为我认为我可以将结果存储在函数之外的变量中。但实际上这似乎是不可能的。

所有这些以及由于我必须对我的培训进行评估。获取不是强制性的。

在我的代码的第一个版本中,我没有使用它。我只是 类 并通过将我的 JSON 加载到变量并将其添加到脚本标记来同步运行。

但是,我想做一些测试,因为那时我必须使用设计模式工厂方法。我刚刚测试过,它适用于您的代码。感谢您在这么晚的时候抽出时间回复我。


//we instantiate the factory
let factory = new identityFactory


     getData.getAll().then(photographers => {

        let identity = photographers
        console.log(identity);
        //we pass the identity in the factory
        let newIdentity = factory.createIdentity(identity,'all')
        console.log(newIdentity);
        showIdentity(newIdentity)

       
    }).catch(err => {
        console.log(err);
    });