简体   繁体   English

如何从承诺中获取价值?

[英]How to get values out of promises?

I have been smashing my head against this problem for a very long time; 很长一段时间以来,我一直在努力解决这个问题。 far too long for what it, almost certainly trivial. 对于它来说太长了,几乎可以肯定是微不足道的。

I want to get a specific value, as if it were returned by a function. 我想获得一个特定的值,就像它是由一个函数返回的一样。 Promises are supposed to be placeholders for values and onAuthRequired takes a function that returns a blocking response object : 承诺应该是值的占位符,onAuthRequired采用一个返回阻塞响应对象的函数

{
  authCredentials: {
    username: "..."
    password: "..."
  }
}

So I need to create a function that returns that structure and does so asynchronously. 因此,我需要创建一个返回该结构并异步执行的函数。 So I put in the async keyword, meaning I can await the resolution of the promise ... I think. 因此,我输入了async关键字,这意味着我可以await promise的解决……我想。 But before I can build that structure, I have to do an asynchronous operation on the nativeMessaging API ... which doesn't return a promise ... I think. 但是,在构建该结构之前,我必须对nativeMessaging API进行异步操作……这不会返回承诺……我想。 So I have to wrap it, somehow, in a promise ... 所以我必须以某种方式将其包装在承诺中...

Edit: I have updated the code below to reflect the current state, an amalgam of all the great responses thus far. 编辑:我已经更新了下面的代码以反映当前状态,到目前为止所有出色的反应都融合在一起。

async function get_data() {
  return new Promise((resolve, reject) => {
    var data = chrome.runtime.sendNativeMessage('Host', {text:'Ready'},
      function(response) {
        resolve(response);
      }
    };
  })
};

async function get_creds() {
  var data = await get_data();
  if (null != data) {
    creds = JSON.parse(data);
    return {
      authCredentials: {
        username: creds.username,
        password: creds.password
      }
    };
  }
};

chrome.webRequest.onAuthRequired.addListener(
  function(details, get_creds),
  {urls: ["<all_urls>"]},
  ['blocking']
);

I experimented with the following code: 我尝试了以下代码:

chrome.webRequest.onAuthRequired.addListener(
  function handler(details){
    var creds = await get_data(); // Uncaught SyntaxError: unexpected identifier
    creds = JSON.parse(creds);
    return {
      authCredentials: {
        username: creds.username,
        password: creds.password
      }
    };
  },
  {urls:["<all_urls>"]},
  ['asyncBlocking']
);

It called get_data() directly but had an unexpected identifier error. 它直接调用了get_data() ,但是出现了意外的标识符错误。

If I removed the await keyword it "worked" ... that is, it tried to do something on the event ... but it didn't pass the object back. 如果我删除了await关键字,它“起作用”了……也就是说,它试图在事件上做某事……但是它没有将对象传递回去。 What it did is set a message in the bottom left of the screen "waiting on extension ... " and call the get_data() function about 3 times. 它所做的是在屏幕的左下方设置一条消息“正在等待扩展...”,并调用get_data()函数约3次。

If I change ['asyncBlocking'] to ['blocking'] , it fails to call get_data() at all. 如果我将['asyncBlocking']更改为['blocking'] ,则根本无法调用get_data()。

I have no idea what's happening here. 我不知道这里发生了什么。


So this should pass the value returned by the Native Messaging Host back via these weird promises and then plug right in to where onAuthRequired expects its JSON structure to be returned ... 因此,这应该通过这些奇怪的承诺将本机消息传递主机返回的值传递回去,然后直接插入到onAuthRequired期望返回其JSON结构的位置...

Edit: I expect the object returned by get_creds() to be passed to onAuthRequired. 编辑:我希望由get_creds()返回的对象传递给onAuthRequired。 At this present point, there's an 'unexpected token' token on function(details, get_creds) ... so that's obviously wrong. 目前,在function(details, get_creds)上有一个'unexpected token'令牌……所以这显然是错误的。 I suspect that I might need to use another promise in get_creds() which will fill in for the authCredentials object ... 我怀疑我可能需要在get_creds()使用另一个promise,它将填充authCredentials对象。

Aside from all the unexpected identifiers whose origin I can't fathom, I've a sense that I'm doing this whole thing backwards. 除了所有我无法理解的出乎意料的标识符之外,我还感觉到我正在把整个事情都倒过来。

Welcome to my wit's end ... and thanks for any light you can shed on my ignorance. 欢迎来到我的机智的结尾...感谢您为我的无知所提供的帮助。

You are returning a promise on get_creds() but you are doing nothing with it. 您在get_creds()上返回了一个promise,但是您对此没有做任何事情。

try to return just the result that you want on get_creds() like this: 尝试仅在get_creds()上返回想要的结果,如下所示:

 async function get_creds() { var data = await get_data(); if (null != data) { var creds = JSON.parse(data) return { authCredentials: { username: creds.username, password: creds.password } }; } else { throw new Error('QuitMyJob'); } } } chrome.webRequest.onAuthRequired.addListener( get_creds(), //should resolve with the value I want to use? {urls: ["<all_urls>"]}, ['blocking'] ); 

Your get_data() method needs to change. 您的get_data()方法需要更改。

sendNativeMessage returns a promise if I am correct. 如果我是正确的, sendNativeMessage返回一个承诺。 Firefox's sendNativeMessage does this returns a promise. Firefox的sendNativeMessage会返回一个承诺。

You need to resolve the promise using .then and then resolve it using the wrapper's resolve callback. 您需要使用.then解析诺言.then然后使用包装程序的resolve回调来解析诺言。

async function get_data() {
  return new Promise((resolve, reject) => {
    var dataPromise = chrome.runtime.sendNativeMessage('Host', {text:'Ready'});
    dataPromise.then(response => {
        resolve(response);
    }).catch(err => {
        reject(err);
    })    
  }
});

If the function does not return a promise, then looks like it accepts and optional callback which will have the response. 如果该函数未返回promise,则看起来它接受并带有响应的可选回调。

https://developer.chrome.com/apps/runtime#method-sendNativeMessage https://developer.chrome.com/apps/runtime#method-sendNativeMessage

async function get_data() {
  return new Promise((resolve, reject) => {
    var dataPromise = chrome.runtime.sendNativeMessage('Host', {text:'Ready'}, function(response) {
      resolve(response);
    });    
  }
});

Also, this, the addListener expects a callback but you seem to be invoking it. 同样,这,addListener期望一个回调,但是您似乎正在调用它。 And the documentation does not show any other arguments. 并且文档没有显示任何其他参数。 You might want to check this https://developer.chrome.com/extensions/webRequest#event-onAuthRequired 您可能要检查此https://developer.chrome.com/extensions/webRequest#event-onAuthRequired

chrome.webRequest.onAuthRequired.addListener(
  get_creds, //should resolve with the value I want to use?
  {urls: ["<all_urls>"]},
  ['blocking']
);

If your function needs to return an object and not a promise (which is what an async function always returns), then a simple function will do: 如果您的函数需要返回一个对象而不是诺言(这是async函数总是返回的),那么一个简单的函数将执行以下操作:

function getData() {
    const data = chrome.runtime.sendNativeMessage('Host', {text:'Ready'});
    if (data) {
        const creds = JSON.parse(data);
        return {
            authCredentials = {
                username: creds.username,
                password: creds.password
            }
        };
    } else {
        // handle the error somehow
    }
};

chrome.webRequest.onAuthRequired.addListener(
  getData
  {urls: ["<all_urls>"]},
  ['blocking']
);

To answer the question "How do I get values out of promises?" 回答“如何从承诺中获得价值”的问题。 I was informed by all 3 provided examples. 提供的所有3个示例都告诉我。 No one had the full solution, however. 但是,没有人有完整的解决方案。

Edit: 编辑:

Full solution to my specific problem (as it happens, it used callbacks, not promises) is here . 完整的解决方案,以我的特定问题(因为它发生,它使用的回调,不承诺)是在这里


Caveat - While I have managed to have an object passed back to onAuthRequest by passing values back through promises, there is some issue with the object, such that it's not having the desired effect. 注意事项 -尽管我设法通过将值通过promises传递回一个对象,从而onAuthRequest对象传递回onAuthRequest ,但该对象还是存在一些问题,以至于无法达到预期的效果。

Firstly, get_data() needed to be changed. 首先,需要更改get_data()

async function get_data() {
  return new Promise((resolve, reject) => {
    const data = chrome.runtime.sendNativeMessage(
      'host',
      {text: "Ready"},
      function(response){
        resolve(response);
      }
    );
  });
});

Next, I was returning a promise on get_creds() (now get_data() ) ... but I wasn't doing anything with it. 接下来,我在get_creds() (现在是get_data() )上返回了一个诺言...但是我没有对此做任何事情。 I needed to use promiseFunction.then(function(response){ ... }) in order to move the resolved value of the promise out. 我需要使用promiseFunction.then(function(response){ ... })才能移出promise的解析值。 This was helpful, too. 也很有帮助。

chrome.webRequest.onAuthRequired.addListener(
  function handler(details){
    get_data().then(function(response) {
      // --> result's value is available in here
      return {
        authCredentials: {
          username: response.username,
          password: response.password
        }
      };
    });
  },
  {urls: ["<all_urls>"]},
  ['asyncBlocking'] // --> not just 'Blocking'
);

Additionally, I needed to return an object - which is done via the callback: 另外,我需要返回一个对象-通过回调完成:

chrome.webRequest.onAuthRequired.addListener(
  function handler(details){ // --> callback
    ...
      return {  // --> an object
        authCredentials: {
          username: response.username,
          password: response.password
        }
    ...
  },
  {urls: ["<all_urls>"]},
  ['asyncBlocking'] // --> not just 'Blocking'
);

Finally, there needs to be a modification of the callback to allow the promise.then() to output something ... Found here 最后,需要对回调进行修改,以允许promise.then()输出某些内容...在这里找到

chrome.webRequest.onAuthRequired.addListener(
  function handler(details){
    get_data().then(function(response) {
... )

becomes: 变为:

chrome.webRequest.onAuthRequired.addListener(
  function handler(details){
    return get_data().then(function(response) {
... )

So that's how to get the value out of that promise and into the callback function... I have more work to do to get the desired result, however. 因此,这就是从该Promise中获取值并进入回调函数的方法...但是,我还有更多工作要做以获得期望的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM