javascript - 如何在 JavaScript 中使用异步函数分配对象值

标签 javascript object asynchronous

我正在构建一个 JavaScript 对象,其中一些值是由异步函数定义的。我的问题是对象的定义速度比异步函数返回值的速度快:

    const array = ['a', 'b', 'c', 'd']
    const myArrayObj = [];

    function returnKey1 () {
        // make async call then store it in the return key1val:
        return key1val
    }

    function returnKey2 () {
        // make async call then store it in the return key2val:
        return key2val
    }

    function returnKey3 () {
        // make async call then store it in the return key3val:
        return key3val
    }

    _.forEach( array, function ( arr ) {
        myArrayObj.push({
            key1: returnKey1(), // returns undefined
            key2: returnKey2(), // returns undefined
            key3: returnKey3(), // returns undefined
      });

    });

有谁知道我应该这样做的正确方法吗?提前致谢!

最佳答案

异步性的本质是,如果您想访问其最终结果,则必须等待异步过程完成。

就您而言,您可以使用 promise 来实现此目的,而无需使用大量代码。:

// promise that resolves after 2 seconds
const timeoutPromise = (str) => new Promise(resolve => setTimeout(() => resolve(str), 2000));

// functions that return promises that will eventually resolve to appropriate key values 

function returnKey1() {
  return timeoutPromise('key3');
}

function returnKey2() {
  return timeoutPromise('key2');
}

function returnKey3() {
  return timeoutPromise('key3');
}

// helper function that returns a promise which will resolve with all the keys when all key-returning promises resolve

function getKeys() {
  return Promise.all([
    returnKey1(),
    returnKey2(),
    returnKey3()
  ])
}

// usage
getKeys().then((keys) => {
  console.log(
    keys[0],
    keys[1],
    keys[2]
  );
});

老式的方法是使用回调而不是 promise ,后者具有更大的浏览器支持,但更加粗糙和原始。

注意:使用现代转译器和/或 Promise 库,您还可以获得对 Promise 的广泛浏览器支持。

// function that calls its callback after 2 seconds
const timeoutCallback = (cb, key) => setTimeout(() => cb(key), 2000);

// functions that eventually call their callbacks with appropriate key values 

function returnKey1(cb) {
  return timeoutCallback(cb, 'key1');
}

function returnKey2(cb) {
  return timeoutCallback(cb, 'key2');
}

function returnKey3(cb) {
  return timeoutCallback(cb, 'key3');
}

// helper function that calls its callback when all the keys are obtained

function getKeys(cb) {
  let keys = [undefined, undefined, undefined];
  let hasAllKeys = () => keys.every(key => typeof key === 'string');

  function makeReturnKeyCallback(idx) {
    return (key) => {
      keys[idx] = key;
      if (hasAllKeys()) {
        cb(keys);
      }
    };
  }

  returnKey1(makeReturnKeyCallback(0));
  returnKey2(makeReturnKeyCallback(1));
  returnKey3(makeReturnKeyCallback(2));
}

// usage
getKeys((keys) => {
  console.log(
    keys[0],
    keys[1],
    keys[2]
  );
});

关于javascript - 如何在 JavaScript 中使用异步函数分配对象值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43433356/

相关文章:

javascript - 表单提交时页面刷新(vanilla javascript)?

javascript - D3 x 和 y 坐标应用于最后附加的元素而不是组

javascript - 如何在 JavaScript 中从键值对对象创建单个对象?

javascript - Object.keys.map 只返回第 n 个值并排除其余值

swift - Firestore addSnapshotListener 在新对象进入时替换对象数据

javascript - 回调函数和 jQuery 的 every 迭代器

javascript - 谷歌地图地理编码器的标记问题(当前和先前的位置标记同时出现)

C# 异步文件传输 - 在继续循环之前等待

multithreading - hibernate session 线程

Javascript Promise 链问题 (Ember)