【问题标题】:Pass value from promise to variable将值从承诺传递给变量
【发布时间】:2018-07-03 18:30:23
【问题描述】:

我试图从 Promise 返回值并将其分配给函数内的局部变量,但 Promise 最终被触发。

函数(将在 Vue.js mounted() 中触发):

getPriceForYesterday(){
    let yesterdayUSD = [];
    for (let i = 0; i < this.cryptos.length; i++) {
        let cryptoName = this.cryptos[i].title;
        let timestamp = new Date(this.cryptos[i].purchaseDate);
        timestamp.setDate(timestamp.getDate() - 1);
        timestamp = timestamp.toISOString();

        let priceYesterday = getPriceForTimestamp(cryptoName, timestamp);
        Promise.all([priceYesterday]).then((values) => {
            console.log("values", values)
            yesterdayUSD.push(values[0]);
        }).catch(e => console.error(e));

    }
    console.log("yesterdayUSD", yesterdayUSD);
    console.log("yesterdayUSD[0]", yesterdayUSD[0]);
}

输出:

yesterdayUSD []
yesterdayUSD[0] undefined
values [13308.06]
values [1278.69]

我想用yesterdayUSD与本地存储值进行比较,然后将比较的“结果”返回给vue数据。

【问题讨论】:

  • 你必须等待所有的 Promise 都解决后才能进行比较。这是因为 Promise 是异步的。你也可以重写或编码并使用 ES6 的异步特性。
  • 你能告诉我如何等待所有已解决的承诺吗?我想我也必须在 ES6 中重写 getPriceForTimestamp(cryptoName, timestamp),因为我也在使用 Promises。
  • 你不必使用 ES6 来处理这个问题。我已经发布了答案。
  • 你能在这个问题上更准确一点吗?这是 UI 显示未定义值的问题吗?在这种情况下,您始终可以使用 v-show / v-if

标签: javascript arrays asynchronous vue.js promise


【解决方案1】:

您在尝试写出昨天USD 时没有看到任何内容的原因是因为 Promise 是异步执行的,并且在到达您使用 console.log() 的行之前它们还没有完成;

我将假设您打算使用 Promise.All() 来等待所有承诺完成,因为这通常是它的用途。我重写了您的示例以填充一系列承诺,然后等待它们全部解决,然后再写出昨天美元中的值。这至少应该允许您在所有承诺完成后打印出值。

getPriceForYesterday(){
    let yesterdayUSD = [];
    let promises = [];

    for (let i = 0; i < this.cryptos.length; i++) {
        let cryptoName = this.cryptos[i].title;
        let timestamp = new Date(this.cryptos[i].purchaseDate);
        timestamp.setDate(timestamp.getDate() - 1);
        timestamp = timestamp.toISOString();

        let priceYesterday = getPriceForTimestamp(cryptoName, timestamp)
            .then((values) => {
                console.log("values", values)
                yesterdayUSD.push(values[0]);
            })
            .catch(e => console.error(e));

        promises.push(priceYesterday);
    }

    Promise.all(promises).finally(() => {
        console.log("yesterdayUSD", yesterdayUSD);
        console.log("yesterdayUSD[0]", yesterdayUSD[0]);
    });
}

【讨论】:

  • 知道为什么昨天USD 和昨天USD[0] 的console.logs 在Promise.finally 中返回“未定义”吗?
  • 它不应该是未定义的。即使它在承诺完成之前执行,昨天USD 至少应该是一个空数组。
【解决方案2】:

也许你也可以重写这个方法/函数来返回一个承诺

getPriceForYesterday(){
    return new Promise( resolve => {
        let yesterdayUSD = [];
        for (let i = 0; i < this.cryptos.length; i++) {
            let cryptoName = this.cryptos[i].title;
            let timestamp = new Date(this.cryptos[i].purchaseDate);
            timestamp.setDate(timestamp.getDate() - 1);
            timestamp = timestamp.toISOString();

            let priceYesterday = getPriceForTimestamp(cryptoName, timestamp);
            Promise.all([priceYesterday])
            .then((values) => {
                yesterdayUSD.push(values[0]);
            })
            .then( () => {
                resolve(yesterdayUSD)
            })

        }
    })
}

然后在mount()方法中使用

mount() {
   ...
   getPriceForYesterday().then( yesterdayUSDArray => {
      //do something with this yesterdayUSDArray
   })
}

【讨论】:

  • 我也可以在函数getPriceForYesterday() 中使用它,还是我真的需要在 mount() 方法中使用它?所以在“return new Promise..”之后。
  • 我真的不知道,我刚刚在 mount() 中写了这个,因为你在问题中说过这个函数是在 Vue 组件的 mount() 方法中触发的。你应该重写它,或者把它放在最适合你的代码的地方。
  • getPriceForYesterday() 函数之外没有对yesterdayUSD 的引用(这并没有多大意义),那么重点是什么。是的,请在问题中更清楚。
猜你喜欢
  • 2013-06-19
  • 2017-07-16
  • 1970-01-01
  • 2018-03-01
  • 2012-01-29
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多