[英]How to assign values by property in nested object array using javascript
[英]How to assign object values using asynchronous functions in javascript
我正在建立一個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庫,您還可以獲得對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] ); });
無論您做什么,都會以諾言告終。 您可以直接使用Promise.all
,或者如果願意花費更多時間,可以為對象編寫自己的Promise.all
版本。 最后,您可以使用async
函數來完成此操作, async
函數是一種以看起來像同步的方式編寫基於promise的代碼的方法。
Promise.all
: // Just examples for testing purposes. function returnKey1() { return promise(); } function returnKey2() { return promise(); } function returnKey3() { return promise(); } // Make a promise returning a random value after random time. function promise() { return new Promise(resolve => { const random = Math.random() * 1000; setTimeout(() => resolve(random), random); }); } // Wait for all promises to finish, then construct result. Promise.all([returnKey1(), returnKey2(), returnKey3()]) .then(([key1, key2, key3]) => ({key1, key2, key3})) .then(console.log);
Promise.all
版本 我們還可以為對象創建Promise.all
的類似物。 一些庫有這樣的例程。 我們將其稱為promiseAllKeys
。 我們將對象的每個屬性值傳遞給一個對象; 它返回一個已填充所有值的對象的Promise.all
。這為我們省去了將從Promise.all
返回的數組轉換為所需對象的麻煩。
function returnKey1() { return promise(); } function returnKey2() { return promise(); } function returnKey3() { return promise(); } function promise() { return new Promise(resolve => { const random = Math.random() * 1000; setTimeout(() => resolve(random), random); }); } // Convenience routine to construct an object from arrays of keys and values. function objectFromKeysAndValues(keys, values) { const result = {}; for (const i = 0; i < keys.length; i++) result[keys[i]] = values[i]; return result; } function promiseAllKeys(promises) { return Promise.all(Object.values(promises)) .then(values => objectFromKeysAndValues(Object.keys(promises), values)); } promiseAllKeys({key1: returnKey1(), key2: returnKey2(), key3: returnKey3()}) .then(console.log);
async/await
您可以使用異步功能簡化代碼。 但是,編寫的這段代碼將等到每個諾言完成后再運行下一個諾言。
function returnKey1() { return promise(); } function returnKey2() { return promise(); } function returnKey3() { return promise(); } function promise() { return new Promise(resolve => { const random = Math.random() * 1000; setTimeout(() => resolve(random), random); }); } async function makeObject() { return {key1: await returnKey1(), key2: await returnKey2(), key3: await returnKey3()}; } makeObject().then(console.log);
簡單但混亂:
const array = ['a', 'b', 'c', 'd']
const myArrayObj = [];
function returnKey1 (cb) {
// make async call then store it in the return key1val:
cb ("key1val");
}
function returnKey2 (cb) {
// make async call then store it in the return key2val:
cb("key2val");
}
function returnKey3 (cb) {
// make async call then store it in the return key3val:
cb("key3val");
}
_.forEach( array, function ( arr ) {
var o ={};
returnKey1(function(key){
o.key1=key;
returnKey2(function(key){
o.key2=key;
returnKey3(function(key){
o.key3=key
myArrayObj.push(obj);
})
})
})
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.