解决对象树中的承诺
Resolve promises in object tree
如何解决foo3
如何在没有 async/await
的情况下仅使用普通 Promise
(不依赖于 regenerator-runtime
)
来解析对象树
const p = v => {
return new Promise(resolve =>
setTimeout(resolve.bind(null, v), 2000)
)
}
const tree = {
element: p('foo'),
children: [
p({
element: 'bar',
children: null
}),
p({
element: 'bar2',
children: [
{
element: p('foo3'),
children: null
}
]
})
]
}
const fullfill = async vtree => {
if(vtree instanceof Promise) {
await vtree
} else if(Array.isArray(vtree)) {
await Promise.all(vtree.map(fullfill))
} else if(typeof vtree !== 'object') {
return vtree
} else {
let { element, children = [] } = vtree
if(element instanceof Promise) {
element = await element
}
if(children.length) {
children = await Promise.all(children.map(fullfill))
}
return {
element,
children
}
}
return vtree
}
fullfill(tree).then(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
您的代码存在问题,您的 children
值 tree
object 由第一个 if (vtree instanceof Promise) {
处理。他们的 child 从未处理过。
为了正确处理 child 我删除了 assigned assign awaited object 回到 vtree
里面 first if
(Change 1) & 在旁边添加 vtree = await fullfill(vtree)
它(更改 2)。
使用 children && children.length 所以如果 children 为 null 那么它不会抛出异常。 (改变 3)
下面进行测试。
const p = v => {
return new Promise(resolve =>
setTimeout(resolve.bind(null, v), 2000)
)
}
const tree = {
element: p('foo'),
children: [
p({
element: 'bar',
children: null
}),
p({
element: 'bar2',
children: [{
element: p('foo3'),
children: null
}]
})
]
}
const fullfill = async vtree => {
if (vtree instanceof Promise) {
// Chanage 1
// assign awaited object back to vtree
vtree = await vtree;
// Chanage 2
// Call fullfill and pass vtree
vtree = await fullfill(vtree);
} else if (Array.isArray(vtree)) {
await Promise.all(vtree.map(fullfill))
} else if (typeof vtree !== 'object') {
return vtree
} else {
let {
element,
children = []
} = vtree
if (element instanceof Promise) {
element = await element
}
// Chanage 3
// use children && children.length so if children is null then it won't throw exception.
if (children && children.length) {
children = await Promise.all(children.map(fullfill));
}
return {
element,
children
}
}
return vtree
}
fullfill(tree).then(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
编辑 没有 await
。要删除 await
,我们需要 return Promise
。请查看第一个代码片段,然后检查第二个代码片段中的等效版本,其中 return Promise
而不是 await
.
下面进行测试。
const p = v => {
return new Promise(resolve =>
setTimeout(resolve.bind(null, v), 2000)
)
}
const tree = {
element: p('foo'),
children: [
p({
element: 'bar',
children: null
}),
p({
element: 'bar2',
children: [{
element: p('foo3'),
children: null
}]
})
]
}
const fullfill = async vtree => {
if (vtree instanceof Promise) {
// Chanage 1
// assign awaited object back to vtree
return vtree.then(r => fullfill(r))
//vtree = await vtree;
//vtree = await fullfill(vtree);
}
// Chanage 2
// update else if condition to if here.
else if (Array.isArray(vtree)) {
return Promise.all(vtree.map(fullfill))
} else if (typeof vtree !== 'object') {
return vtree
} else {
let {
element,
children = []
} = vtree
if (element instanceof Promise) {
// element = await element
return element.then(e => {
if (children && children.length) {
return Promise.all(children.map(fullfill)).then(c => ({
element: e,
children: c
}));
};
return {
element: e,
children: children
};
});
}
// Chanage 3
// use children && children.length so if children is null then it won't throw exception.
else if (children && children.length) {
return Promise.all(children.map(fullfill)).then(c => ({
element: element,
children: c
}));
}
}
return vtree
}
fullfill(tree).then(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
如果您所做的只是 return
结果,那么几乎没有理由使用 async
/await
。您只会将它用于树节点(元素+子节点)的情况,但您也可以在 之后轻松地使用 then
进行转换:
function treeAll(vtree) {
if (typeof vtree !== 'object' || vtree == null) {
return Promise.resolve(vtree);
} else if (vtree instanceof Promise) {
return vtree.then(treeAll);
} else if (Array.isArray(vtree)) {
return Promise.all(vtree.map(treeAll));
} else {
return Promise.all([
vtree.element,
treeAll(vtree.children)
]).then(([element, children]) => ({
element,
children
}));
}
}
如何解决
foo3
如何在没有
来解析对象树async/await
的情况下仅使用普通Promise
(不依赖于regenerator-runtime
)
const p = v => {
return new Promise(resolve =>
setTimeout(resolve.bind(null, v), 2000)
)
}
const tree = {
element: p('foo'),
children: [
p({
element: 'bar',
children: null
}),
p({
element: 'bar2',
children: [
{
element: p('foo3'),
children: null
}
]
})
]
}
const fullfill = async vtree => {
if(vtree instanceof Promise) {
await vtree
} else if(Array.isArray(vtree)) {
await Promise.all(vtree.map(fullfill))
} else if(typeof vtree !== 'object') {
return vtree
} else {
let { element, children = [] } = vtree
if(element instanceof Promise) {
element = await element
}
if(children.length) {
children = await Promise.all(children.map(fullfill))
}
return {
element,
children
}
}
return vtree
}
fullfill(tree).then(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
您的代码存在问题,您的 children
值 tree
object 由第一个 if (vtree instanceof Promise) {
处理。他们的 child 从未处理过。
为了正确处理 child 我删除了 assigned assign awaited object 回到 vtree
里面 first if
(Change 1) & 在旁边添加 vtree = await fullfill(vtree)
它(更改 2)。
使用 children && children.length 所以如果 children 为 null 那么它不会抛出异常。 (改变 3)
下面进行测试。
const p = v => {
return new Promise(resolve =>
setTimeout(resolve.bind(null, v), 2000)
)
}
const tree = {
element: p('foo'),
children: [
p({
element: 'bar',
children: null
}),
p({
element: 'bar2',
children: [{
element: p('foo3'),
children: null
}]
})
]
}
const fullfill = async vtree => {
if (vtree instanceof Promise) {
// Chanage 1
// assign awaited object back to vtree
vtree = await vtree;
// Chanage 2
// Call fullfill and pass vtree
vtree = await fullfill(vtree);
} else if (Array.isArray(vtree)) {
await Promise.all(vtree.map(fullfill))
} else if (typeof vtree !== 'object') {
return vtree
} else {
let {
element,
children = []
} = vtree
if (element instanceof Promise) {
element = await element
}
// Chanage 3
// use children && children.length so if children is null then it won't throw exception.
if (children && children.length) {
children = await Promise.all(children.map(fullfill));
}
return {
element,
children
}
}
return vtree
}
fullfill(tree).then(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
编辑 没有 await
。要删除 await
,我们需要 return Promise
。请查看第一个代码片段,然后检查第二个代码片段中的等效版本,其中 return Promise
而不是 await
.
下面进行测试。
const p = v => {
return new Promise(resolve =>
setTimeout(resolve.bind(null, v), 2000)
)
}
const tree = {
element: p('foo'),
children: [
p({
element: 'bar',
children: null
}),
p({
element: 'bar2',
children: [{
element: p('foo3'),
children: null
}]
})
]
}
const fullfill = async vtree => {
if (vtree instanceof Promise) {
// Chanage 1
// assign awaited object back to vtree
return vtree.then(r => fullfill(r))
//vtree = await vtree;
//vtree = await fullfill(vtree);
}
// Chanage 2
// update else if condition to if here.
else if (Array.isArray(vtree)) {
return Promise.all(vtree.map(fullfill))
} else if (typeof vtree !== 'object') {
return vtree
} else {
let {
element,
children = []
} = vtree
if (element instanceof Promise) {
// element = await element
return element.then(e => {
if (children && children.length) {
return Promise.all(children.map(fullfill)).then(c => ({
element: e,
children: c
}));
};
return {
element: e,
children: children
};
});
}
// Chanage 3
// use children && children.length so if children is null then it won't throw exception.
else if (children && children.length) {
return Promise.all(children.map(fullfill)).then(c => ({
element: element,
children: c
}));
}
}
return vtree
}
fullfill(tree).then(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
如果您所做的只是 return
结果,那么几乎没有理由使用 async
/await
。您只会将它用于树节点(元素+子节点)的情况,但您也可以在 then
进行转换:
function treeAll(vtree) {
if (typeof vtree !== 'object' || vtree == null) {
return Promise.resolve(vtree);
} else if (vtree instanceof Promise) {
return vtree.then(treeAll);
} else if (Array.isArray(vtree)) {
return Promise.all(vtree.map(treeAll));
} else {
return Promise.all([
vtree.element,
treeAll(vtree.children)
]).then(([element, children]) => ({
element,
children
}));
}
}