Javascript 将成功承诺解析的值分配给外部变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31264153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:26:55  来源:igfitidea点击:

Assign value from successful promise resolve to external variable

javascriptangularjs

提问by Gerard Clos

I have a pretty silly problem. Consider the following:

我有一个非常愚蠢的问题。考虑以下:

vm.feed = getFeed().then(function(data) {return data;});

getFeed()returns a $q deferred promise (I am on angular) that resolves successfully.

getFeed()返回一个成功解决的 $q 延迟承诺(我在角度)。

My goal is to set vm.feed equal to the data value returned by the successful callback. As it is right now, the code simply assigns vm.feed equal to the $promiseobject returned by getFeed().

我的目标是设置 vm.feed 等于成功回调返回的数据值。就像现在一样,代码只是简单地将 vm.feed 分配为等于$promise返回的对象getFeed()

I know I could simply do: vm.feed = datainside the resolved function but I want to understand why this code does not work as it is.

我知道我可以简单地做:vm.feed = data在已解析的函数中,但我想了解为什么这段代码不能正常工作。

PD: the promise resolves correctly and even after it has been resolved vm.feed keeps being equal to the Promise, and not data. I copy the console.log of vm.feed after +10 seconds have elapsed:

PD:promise 正确解析,即使在解析后 vm.feed 仍然等于 Promise,而不是数据。我在 10 秒后复制 vm.feed 的 console.log:

Promise {$$state: Object} $$state: Objectstatus:1 value: Object

That value property inside the Promise object contains the actual solution of the promise that I want to assign to vm.feed (e.i. data).

Promise 对象中的 value 属性包含我要分配给 vm.feed (ei data)的承诺的实际解决方案。

thank you!

谢谢你!

采纳答案by Nathan

Your statement does nothing more than ask the interpreter to assign the value returned from then()to the vm.feedvariable. then()returns you a Promise (as you can see here: https://github.com/angular/angular.js/blob/master/src/ng/q.js#L283). You could picture this by seeing that the Promise (a simple object) is being pulledout of the function and getting assigned to vm.feed. This happens as soon as the interpreter executes that line.

您的发言确实不外乎要求解释分配从返回的值then()vm.feed变量。then()返回一个 Promise(如您所见:https: //github.com/angular/angular.js/blob/master/src/ng/q.js#L283)。您可以通过看到 Promise(一个简单的对象)被从函数中拉出并被分配给vm.feed. 一旦解释器执行该行,就会发生这种情况。

Since your successful callback does not run when you call then()but only when your promise gets resolved (at a later time, asynchronously) it would be impossible for then()to return its value for the caller. This is the default way Javascript works. This was the exact reason Promises were introduced, so you could ask the interpreter to pushthe value to you, in the form of a callback.

由于您的成功回调不会在您调用then()时运行,而只有在您的承诺得到解决时(稍后,异步),因此不可能为then()调用者返回其值。这是 Javascript 的默认工作方式。这就是引入 Promise 的确切原因,因此您可以要求解释器以回调的形式将值送给您。

Though on a future version that is being worked on for JavaScript (ES2016) a couple keywords will be introduced to work pretty much as you are expecting right now. The good news is you can start writing code like this today through transpilation from ES2016 to the current widely supported version (ES5).

尽管在为 JavaScript (ES2016) 开发的未来版本中,将引入几个关键字,它们的工作方式与您现在所期望的差不多。好消息是,您可以通过从 ES2016 转换为当前广泛支持的版本 (ES5) 来开始编写这样的代码。

A nice introduction to the topic is available at: https://www.youtube.com/watch?v=lil4YCCXRYc

有关该主题的精彩介绍,请访问:https: //www.youtube.com/watch?v=lil4YCCXRYc

To use it right now you can transpile your code through Babel: https://babeljs.io/docs/usage/experimental/(by running with --stage 1).

要立即使用它,您可以通过 Babel 转译您的代码:https://babeljs.io/docs/usage/experimental/ (通过使用 运行--stage 1)。

You can also see some examples here: https://github.com/lukehoban/ecmascript-asyncawait.

您还可以在此处查看一些示例:https: //github.com/lukehoban/ecmascript-asyncawait

回答by Soldeplata Saketos

This could be updated to ES6 with arrow functions and look like:

这可以使用箭头函数更新到 ES6,如下所示:

getFeed().then(data => vm.feed = data);

If you wish to use the async function, you could also do like that:

如果你想使用async function,你也可以这样做:

async function myFunction(){
    vm.feed = await getFeed();
    // do whatever you need with vm.feed below
 }

回答by BhavO

The then()method returns a Promise. It takes two arguments, both are callback functions for the success and failure cases of the Promise. the promise object itself doesn't give you the resolved data directly, the interface of this object only provides the data via callbacks supplied. So, you have to do this like this:

then()方法返回一个 Promise。它需要两个参数,都是 Promise 成功和失败案例的回调函数。promise 对象本身不会直接为您提供解析的数据,该对象的接口仅通过提供的回调提供数据。所以,你必须这样做:

getFeed().then(function(data) { vm.feed = data;});

The then()function returns the promise with a resolved value of the previous then()callback, allowing you the pass the value to subsequent callbacks:

then()函数返回具有前一个then()回调的已解析值的承诺,允许您将值传递给后续回调:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

// promiseB will be resolved immediately after promiseA is resolved
// and its value will be the result of promiseA incremented by 1

回答by Smartens

You could provide your function with the object and its attribute. Next, do what you need to do inside the function. Finally, assign the value returned in the promise to the right place in your object. Here's an example:

您可以为您的函数提供对象及其属性。接下来,在函数内部执行您需要执行的操作。最后,将 promise 中返回的值分配到对象中的正确位置。下面是一个例子:

let myFunction = function (vm, feed) {
    getFeed().then( data => {
        vm[feed] = data
    })
} 

myFunction(vm, "feed")

You can also write a self-invoking function if you want.

如果需要,您还可以编写自调用函数。

回答by Rodrigo Moura

This is one "trick" you can do since your out of an async function so can't use await keywork

这是你可以做的一个“技巧”,因为你没有异步功能所以不能使用 await keywork

Do what you want to do with vm.feed inside a setTimeout

在 setTimeout 中用 vm.feed 做你想做的事

vm.feed = getFeed().then(function(data) {return data;});

 setTimeout(() => {
    // do you stuf here
    // after the time you promise will be revolved or rejected
    // if you need some of the values in here immediately out of settimeout
    // might occur an error if promise wore not yet resolved or rejected
    console.log("vm.feed",vm.feed);
 }, 100);