int to hex:
int a = 72;
Console.WriteLine ("{0: X}", a);
blockquote>hex to int:
int b = 0xB76;
Console.WriteLine (b);
blockquote>
Как упоминалось в комментариях, Array.prototype.filter
является синхронным и, следовательно, не поддерживает Promises.
Так как теперь вы можете (теоретически) создавать подклассы встроенных типов с ES6, вы должны иметь возможность добавлять свои собственный асинхронный метод, который обертывает существующую функцию фильтра:
Примечание: Я прокомментировал подклассу, потому что он еще не поддерживается Вавилем еще для Массивов
class AsyncArray /*extends Array*/ {
constructor(arr) {
this.data = arr; // In place of Array subclassing
}
filterAsync(predicate) {
// Take a copy of the array, it might mutate by the time we've finished
const data = Array.from(this.data);
// Transform all the elements into an array of promises using the predicate
// as the promise
return Promise.all(data.map((element, index) => predicate(element, index, data)))
// Use the result of the promises to call the underlying sync filter function
.then(result => {
return data.filter((element, index) => {
return result[index];
});
});
}
}
// Create an instance of your subclass instead
let arr = new AsyncArray([1,2,3,4,5]);
// Pass in your own predicate
arr.filterAsync(async (element) => {
return new Promise(res => {
setTimeout(() => {
res(element > 3);
}, 1);
});
}).then(result => {
console.log(result)
});
Допустимый способ сделать это (но кажется слишком запутанным):
let arr = [1,2,3];
function filter(num) {
return new Promise((res, rej) => {
setTimeout(() => {
if( num === 3 ) {
res(num);
} else {
rej();
}
}, 1);
});
}
async function check(num) {
try {
await filter(num);
return true;
} catch(err) {
return false;
}
}
(async function() {
for( let num of arr ) {
let res = await check(num);
if(!res) {
let index = arr.indexOf(num);
arr.splice(index, 1);
}
}
})();
Опять же, кажется слишком запутанным.
async
/ await
являются ES7 (Кандидат), а не ES6
– CodingIntrigue
27 October 2015 в 08:38
Promise Reducer на помощь!
[1, 2, 3, 4].reduce((op, n) => {
return op.then(filteredNs => {
return new Promise(resolve => {
setTimeout(() => {
if (n >= 3) {
console.log("Keeping", n);
resolve(filteredNs.concat(n))
} else {
console.log("Dropping", n);
resolve(filteredNs);
}
}, 1000);
});
});
}, Promise.resolve([]))
.then(filteredNs => console.log(filteredNs));
Редукторы потрясающие. «Уменьшите мою проблему до моей цели», похоже, является довольно хорошей стратегией для чего-либо более сложного, чем простые решения для вас, т. Е. Фильтрация массива вещей, которые не все доступны сразу.
Это элегантное решение 2017 с использованием async / await:
Очень простое использование:
const results = await filter(myArray, async num => {
await doAsyncStuff()
return num > 2
})
Вспомогательная функция (скопируйте это на свою веб-страницу):
async function filter(arr, callback) {
const fail = Symbol()
return (await Promise.all(arr.map(async item => (await callback(item)) ? item : fail))).filter(i=>i!==fail)
}
Демонстрация:
// Async IIFE
(async function() {
const myArray = [1, 2, 3, 4, 5]
// This is exactly what you'd expect to write
const results = await filter(myArray, async num => {
await doAsyncStuff()
return num > 2
})
console.log(results)
})()
// Arbitrary asynchronous function
function doAsyncStuff() {
return Promise.resolve()
}
// The helper function
async function filter(arr, callback) {
const fail = Symbol()
return (await Promise.all(arr.map(async item => (await callback(item)) ? item : fail))).filter(i=>i!==fail)
}
Я даже выброшу код CodePen .
filter([1, 2, undefined, 3], (x) => x !== 1)
вернет [2, 3]
, а не [2, undefined, 3]
, как и должно быть.
– Tim Perry
4 December 2017 в 11:48
Symbol
сторожевого устройства вместо undefined
.
– Tamlyn
30 April 2018 в 14:55
undefined
:)
– Gabe Rogan
30 April 2018 в 15:30
Вот способ:
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var filter = num => wait(1).then(() => num == 3);
var filterAsync = (array, filter) =>
Promise.all(array.map(entry => filter(entry)))
.then(bits => array.filter(entry => bits.shift()));
filterAsync([1,2,3], filter)
.then(results => console.log(results.length))
.catch(e => console.error(e));
Функция filterAsync
принимает массив и функцию, которые должны либо возвращать true
, либо false
или возвращать обещание, которое разрешает true
или false
, что вы просили (почти, я не перегружал обещание, потому что считаю, что это плохая идея). Дайте мне знать, если у вас есть какие-либо вопросы по этому поводу.
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var filter = num => wait(1).then(() => num == 3);
var filterAsync = (array, filter) =>
Promise.all(array.map(entry => filter(entry)))
.then(bits => array.filter(entry => bits.shift()));
filterAsync([1,2,3], filter)
.then(results => console.log(results.length))
.catch(e => console.error(e));
var console = { log: msg => div.innerHTML += msg + "<br>",
error: e => console.log(e +", "+ (e.lineNumber-25)) };
<div id="div"></div>
Вариант @ DanRoss's:
async function filterNums(arr) {
return await arr.reduce(async (res, val) => {
res = await res
if (await filter(val)) {
res.push(val)
}
return res
}, Promise.resolve([]))
}
Обратите внимание, что если (как в текущем случае) вам не нужно беспокоиться о том, что filter () имеет побочные эффекты, которые необходимо сериализовать, вы можете также делают:
async function filterNums(arr) {
return await arr.reduce(async (res, val) => {
if (await filter(val)) {
(await res).push(val)
}
return res
}, Promise.resolve([]))
}
Поздно к игре, но поскольку никто больше не упомянул об этом, Bluebird поддерживает Promise.map, который является моим ходом для фильтров, требующих обработки aysnc для условия,
function filterAsync(arr) {
return Promise.map(arr, num => {
if (num === 3) return num;
})
.filter(num => num !== undefined)
}
super()
необходимо вызвать перед любым присваиваниемthis
внутриconstructor
– Farzad YZ 21 April 2017 в 17:05