因此,我很高兴一直在使用async / await,因为Firebase Cloud Functions支持节点8。我正在努力做一件事情。使用可调用函数时,系统会告知您必须在函数中返回一个promise,否则它将无法正常工作。使用原始的诺言时,我很清楚如何使用它:
Eigen::Map<Eigen::SparseMatrix<float>> sparse_map(num_rows, num_cols, num_non_zeros,
original_outer_index_ptr, original_inner_index_ptr,
original_values_ptr);
但是现在,异步等待着,我不确定如何返回这个“承诺链”:
exports.createBankAccount = functions.region('europe-west1').https.onCall((data, context) => {
return promiseMethod().then((result) => {
return nextPromise(result);
}).then((result) => {
return result;
}).catch((err) => {
// handle err
})
});
有人知道吗?
答案 0 :(得分:1)
HTTP函数不返回承诺。他们只是发送结果。您仍然必须正确使用Promise才能发送结果,但是不需要返回值。发送响应后,HTTP函数将终止。参见documentation for more details:
使用res.redirect(),res.send()或res.end()终止HTTP函数。
答案 1 :(得分:1)
你用你的示例代码搞定了。
Async/await 只是一种较新的承诺方式。它们可以互换使用。
这是一个相同函数的 promise 和 async/await 示例。
这个
exports.createBankAccount = functions.region('europe-west1').https.onCall((data, context) => {
return promiseMethod().then((result) => {
return nextPromise(result);
}).catch((err) => {
// handle error here
})
});
相当于:
exports.createBankAccount = functions.region('europe-west1').https.onCall(async (data, context) => {
try {
const result = await promiseMethod();
return nextPromise(result); // You are returning a promise here
}catch(e) {
// handle error here
}
});
请注意,在这两种情况下,您都在最后返回了一个承诺。这个 onCall 函数的返回值是 nextPromise(result)
的任何值。由于您正在返回 nextPromsie(result)
,因此您无需等待。
答案 2 :(得分:1)
要查看问题的代码解决方案,请查看 dshukertjr 的答案。
如果你想了解如何使用 async/await 返回一个“承诺链”,这里是你的答案:
你不能! 为什么 ?因为 await 用于等待 Promise 完成。一旦 await 返回一个值,他们就不再是 Promise。
因此,如果您绝对想使用 await 返回承诺,则可以等待两个返回承诺的函数之一,但不能同时等待。
这里有两种方法:
答:
exports.createBankAccount = functions.region('europe-west1').https.onCall(async (data, context) => {
try {
const result = await promiseMethod();
return nextPromise(result); // You are returning a promise here
}catch(e) {
// handle error here
}
});
乙:
exports.createBankAccount = functions.region('europe-west1').https.onCall(async (data, context) => {
return promiseMethod().then(async (result) => {
return await nextPromise(result);
}).catch((err) => {
// handle err
})
});
A 和 B 的唯一区别是 A 在返回 Promise 之前等待“PromiseMethod”完成。而 B 在被调用后立即返回一个 Promise。
答案 3 :(得分:0)
似乎,我们必须以这种方式等待几个承诺:
const listOfAsyncJobs = [];
listOfAsyncJobs.push(createThumbnail(1, ...));
listOfAsyncJobs.push(createThumbnail(2, ...));
listOfAsyncJobs.push(createThumbnail(3, ...));
...
return Promise.all(listOfAsyncJobs); // This will ensure we wait for the end of the three aync tasks above.
答案 4 :(得分:0)
从异步方法返回的任何内容都会自动包装在 promise 中。 例如
const myFun = async () => {return 5}
myFun();
// Output in the console
Promise {<fulfilled>: 5}
你可以链接返回的结果,因为它是一个承诺
其他答案中建议的增强功能的另一个示例
const myFun4 = async () => {
const myNum = await new Promise(r => window.setTimeout(() => r(5), 1000));
const myNum2 = await new Promise(r => window.setTimeout(() => r(5), 1000));
return myNum + myNum2;
}
myFun4().then((n) => console.log(n));
// Output
10
答案 5 :(得分:0)
async-await
函数的返回值为 Promise
。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#return_value
所以,您实际上所做的是返回一系列承诺。
const nextPromise = () => {
console.log('next promise!');
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('next promise result')
}, 3000)
});
}
const promiseMethod = () => {
console.log('promise!');
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise result');
}, 2000)
});
}
exports.createBankAccount = functions.https.onCall((data, context) => {
return promiseMethod().then((result) => {
return nextPromise(result);
}).then((result) => {
return result;
}).catch((err) => {
// handle err
console.log(err);
})
});
exports.createBankAccountAsync = functions.https.onCall(async (data, context) => {
const result = await promiseMethod();
const res = await nextPromise(result);
return res;
});
答案 6 :(得分:0)
这种情况下的解决方案是 Promise.all()
。
exports.createBankAccount = functions.region('europe-west1').https.onCall(async (data, context) => {
const promises = [];
const res1 = await promiseMethod();
const res2 = await nextPromise(res1);
promises.push(res1);
promises.push(res2);
// Here's the return of the promises
return Promise.all(promises).catch(error => console.error(error));
});
上的这篇文章中找到有关 Promise 的更多信息
答案 7 :(得分:0)
由于您需要返回承诺,因此您可以创建承诺对象并在处理所有承诺后从 api 解析/拒绝(返回)您的响应。
选项 1:
exports.createBankAccount = functions.region('europe-west1').https.onCall((data, context) => {
return new Promise(async (resolve, reject) => {
try {
const res1 = await promiseMethod();
const res2 = await nextPromise(res1);
// This will return response from api
resolve(res2);
}
catch (err) {
// Handle error here
// This will return error from api
reject(err)
}
})
});
选项 2:
exports.createBankAccount = functions.region('europe-west1').https.onCall((data, context) => {
return new Promise(async (resolve, reject) => {
const res1 = await promiseMethod();
const res2 = await nextPromise(res1);
// This will return response from api
resolve(res2);
})
.then((val) => val)
.catch((err) => {
// Handle error here
// This will return error from api
return err
})
});
答案 8 :(得分:-1)
仅在需要时转换为Promise。
即如果nextPromise返回一个Promise:
exports.createBankAccount = functions.region('europe-west1').https.onCall(async (data, context) => {
const res1 = await promiseMethod();
return nextPromise(res1);
});
另一方面,如果nextPromise是异步函数,只需将其转换为Promise:
exports.createBankAccount = functions.region('europe-west1').https.onCall(async (data, context) => {
const res1 = await promiseMethod();
return Promise.resolve(nextPromise(res1));
});
您还可以转换结果:
exports.createBankAccount = functions.region('europe-west1').https.onCall(async (data, context) => {
const res1 = await promiseMethod();
const res2 = await nextPromise(res1);
return Promise.resolve(res2);
});
答案 9 :(得分:-1)
编写异步函数时,代码实际上将退出该函数,并在遇到的第一个等待时返回Promise。等待之后的所有代码都将转换为then()。
因此,对于Firebase而言,使用async / await编写代码是完全可以节省的,并且根据我的经验,甚至更不容易出错,因为我可以更轻松地在代码中构造try&catch!
只需在您的控制台中运行它即可
struct User {
var name: String!
var age: Int!
var hasPet: Bool!
var pets: [Pets]!
}
struct Pets {
var id: Int!
var petName: String!
var colour: String!
}
将打印:let petsFiltered = users.filter { (user) -> Bool in
return (user.pets.)!
}