承诺我在使用回调时返回挂起状态 [英] promise me return a pending state when I use a callback

查看:43
本文介绍了承诺我在使用回调时返回挂起状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过回调测试提取API,但是我的函数返回"Promise State:Pending",但我不明白为什么:

 异步函数getJson(url,callback){等待获取(URL).then(异步函数(响应){返回等待response.json()}).then(function(data){console.log(数据)回调(数据)})}让getData = {getAll:异步函数(){等待getJson('js/getJson/data.json',function(data){console.log(data.photographers)//确定让测试= data.photographers退货测试})}}console.log(getData.getAll());//待处理的返回承诺 

谢谢

解决方案

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

这是 getJson()的样子:

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

只返回 fetch()已经返回的承诺-不要尝试转换为回调.从编程可用性的角度来看,将基于promise的接口转换为回调接口正在倒退.与异步编程的普通回调相比,使用Promise编程要好得多.

以下是 getAll()可以如何使用它的方法:

  const getData = {getAll:异步函数(){const data =等待getJson('js/getJson/data.json');返回数据}} 

或者,同样好(并等同于上面的示例)是这样的:

  const getData = {getAll:function(){返回getJson('js/getJson/data.json').then(data => {返回数据});}} 

当您对多个异步操作进行排序时,

await 具有显着的优势,但是当只有一个异步操作时,通常并没有多大帮助.那么使用它并没有错,只是它并没有提供太多帮助.

而且,这就是调用 getAll()的方式:

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

一般建议和解释:

1.阅读并研究 async await 如何与promises一起使用.只有在了解了这一点后,才使用它,然后您将只使用 await 当您等待诺言时.除非您正在等待一个Promise,否则 await 不会做任何有用的事情,因此,如果您正在等待一个函数调用,则该函数必须返回一个Promise,并且当该函数中的异步操作被执行时,该Promise必须与之连接.完成.

2.请勿混用普通的回调和Promise..如果您在使用Promise接口进行编程,请使用该Promise-切勿将其转换为普通的回调.从您的函数中返回一个承诺,并让调用者使用它.发明诺言的许多原因之一是,非简单异步操作中的控制流程通过诺言(特别是异步错误处理和向更高级别的错误传播)大大简化了.

3.将普通的回调转换为Promise.如果您遇到了要在存在其他基于Promise的异步操作(例如 fetch())的世界中使用的异步操作,请进行包装普通的回调到Promise接口中,因此您仅将基于Promise的调用与其他基于Promise的调用混合在一起.可靠地编码要简单得多.

4. async 函数始终返回承诺.这就是它们在Javascript内部构建的方式.因此, async 函数的调用者始终会返回一个promise作为返回值.该承诺最初将处于 pending 状态.它将在将来的某个时间解决,并且promise的最终解决值将是从 async 函数的外部范围返回的任何值.如果在 async 函数的外部范围中没有 return 语句,则解析的值将是 undefined ,与您的`async一样功能.

5.呼叫者使用 .then() await 从诺言中获得已解决的值.这是从诺言中获得已解决的值的仅有两种方法.因此,想要从中获取一些值的 async 函数的任何调用者都需要使用 .then() await 来获取该值.

6.如果您在函数内部有一个基于promise的操作,并且希望从函数中返回其已解决的值,则只需从函数中返回该promise..这将允许调用者使用该promise来获取值.请参阅上面的 getJson()实现,以了解它的简单程度.

7.避免使用 return await fn(),而改用 return fn().如果您使用的是 Return await fn(),那么您已经在 async 函数中,因此该函数已经返回了promise.因此,请避免使用多余的 await ,因为它不会做任何有用的事情,而只需使用 return fn().如果 fn()返回一个值,则该值将成为您的 async 函数返回的Promise的已解析值.如果 fn()返回一个Promise,则该Promise的解析值将成为您的 async 函数返回的Promise的解析值.

8.从 .then()处理程序返回一个值将成为父承诺的已解析值.在上述第二个使用 getData()示例中在.then()内部, return data.photographers; 语句将父承诺的解析值设置为 data.photographers .因此,任何 getData()的调用者都将发现 data.photographers 成为 getData()返回的承诺的已解决值.

9.从 .then()处理程序返回一个promise链接该promise,您返回的promise的已解析值将成为父promise的已解析值.本质上,从 .then()使父承诺等待新返回的承诺解决,然后从新返回的承诺中获取其已解决的值.您可以在 getJson()函数中看到这一点,其中 response.json()返回一个新的promise,它将解析为http请求的json解析的正文.该解析值将成为该函数返回的承诺的解析值.

10.如果希望将回调传递给某个异步函数,则大多数情况下该函数将不会返回承诺,因为这些天许多异步API都接受一个回调或返回Promise,但不要同时执行.因此,在尝试使用 await 时,请绝对确保您正在等待的函数正在返回promise.如有疑问,请查看文档.如果文档不清楚,请查看该函数本身的代码,或者进行实验以查看实际的返回值.例如,大多数mongodb异步API如果不将回调传递给它们,则将返回promise,但是如果您传递回调,则将不返回promise.使用一个或另一个,而不是两个都使用.

I test the fetch API with a callback, but my function returns "Promise State: Pending", and I don't understand why :

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

Thanks

解决方案

General advice for asynchronous and promise-based programming listed below...

Here's what getJson() should look like:

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

Just return the promise that fetch() already returned - don't try to convert to a callback. Converting a promise-based interface to a callback interface is going backwards in terms of programming usability. Promises are much better to program with than plain callbacks for asynchronous programming.

Here's how getAll() can then use it:

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

Or, equally good (and equivalent to the above example) would be this:

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

await has significant advantages when you are sequencing more than one asynchronous operation, but usually doesn't really help much when there's just one asynchronous operation. It's not wrong to use it then, it just doesn't really offer much help.

And, here's how one would call getAll():

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

General Advice and Explanation:

1. Read and study how async and await work with promises. Only use it once you understand that and then you will only be using await when you are awaiting a promise. await does nothing useful unless you are awaiting a promise so if you're awaiting a function call, then that function must be returning a promise and that promise must be connected to when the asynchronous operations in that function are completed.

2. Don't mix plain callbacks and promises. If you are programming with a promise interface, use that promise - never convert it to a plain callback. Return a promise from your function and let the caller use that. Among the many, many reasons that promises were invented is that control flow in non-simple asynchronous operations is massively simpler with promises (particularly asynchronous error handling and error propagation to higher levels).

3. Convert plain callbacks to promises. If you encounter an asynchronous operation that you want to use in a world where there are other promise-based asynchronous operations (such as fetch()), then wrap the plain callback into a promise interface so you are only mixing promise-based calls with other promise-based calls. Much, much simpler to code reliably.

4. async functions ALWAYS return a promise. That's how they are built internal to Javascript. So, a caller of an async function always gets back a promise as the return value. That promise will initially be in the pending state. It will be resolved sometime in the future and the eventual resolved value of the promise will be whatever value is returned from the outer scope of the async function. If there's no return statement in the outer scope of the async function, then the resolved value will be undefined as it is with both your `async functions.

5. A caller gets a resolved value from a promise with .then() or await. Those are the only two ways to get a resolved value out of a promise. So, any caller of an async function that wants some value back from it needs to use .then() or await to get that value.

6. If you have a promise-based operation inside a function and you wish to return it's resolved value from your function, then just return that promise from the function. That will allow the caller to use that promise to get the value. See my getJson() implementation above for how simple that can be.

7. Avoid return await fn() and use return fn() instead. If you're using return await fn(), then you're already in an async function and thus the function is already returning a promise. So, avoid the extra await as it doesn't do anything useful and just use return fn(). If fn() returns a value that value will become the resolved value of the promise that your async function returned. If fn() returns a promise, then the resolved value of that promise will become the resolved value of the promise that your async function returned.

8. Returning a value from a .then() handler becomes the resolved value of the parent promise. In the second getData() example above that uses .then() internally, the return data.photographers; statement sets the resolved value of the parent promise to data.photographers. So, any caller of getData() will find that data.photographers becomes the resolved value of the promise that getData() returns.

9. Returning a promise from a .then() handler chains the promises and the resolved value of the promise you return becomes the resolved value of the parent promise. Essentially, returning a promise from a .then() causes the parent promise to wait for the newly returned promise to resolve and it then gets its resolved value from that newly returned promise. You can see this in play in the getJson() function where response.json() returns a new promise that resolves to the json-parsed body of the http request. That resolved value will become the resolved value of the promise that the function returned.

10. Don't pass a callback when expecting a promise back. If you're passing a callback to some asynchronous function, then most of the time that function will not be returning a promise because many asynchronous APIs these days accept either a callback or return a promise, but don't do both at the same time. So, when looking to use await, make absolutely sure the function you're awaiting is returning a promise. When in doubt, look at the doc. If the doc is unclear look at the code for the function itself or run an experiment to see what the return value actually is. As an example, most of the mongodb asynchronous APIs will return a promise if you do NOT pass a callback to them, but will not return a promise if you do pass the callback. Use one or the other, not both.

这篇关于承诺我在使用回调时返回挂起状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆