如何以同步方式制作 Promise API?
How to make Promise API in a synchronous way?
我使用 selenium-webdriver 来测试 NodeJS。
我想以同步方式制作 selenium-webdriver API ,让我的测试非常简洁。
getTitle() 安排一个命令来检索当前页面的标题。这个APIreturn一个webdriver.promise.Promise
例如 selenium-webdriver 我做
driver.getTitle().then(function(title) {
.....
});
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
如何做到完全同步API(使API Promise 同步?),像这样
var titleElement = driver.getTitle();
var qElement= driver.findElement(webdriver.By.name('q'));
qElement.sendKeys('webdriver');
更新(Benjamin Gruenbaum 回复):
使用 yield with Promise.coroutine from bluebird API
function myBrowser() {
}
myBrowser.prototype.getTitle = Promise.coroutine(function* (driver) {
var title = yield driver.getTitle(); // yield makes it wait
console.log('prototype.getTitle: ' + title)
return title;
});
var driver = createDriver();
driver.get('https://www.google.fr/')
driver.getTitle().then(function(title) {
console.log('getTitle: ' + title)
});
// Use bluebird API
var mb = new myBrowser();
var title = mb.getTitle(driver)
// KO, It' an object Promise, not string title
console.log('main Process: ' + title)
输出
[INFO:CONSOLE(0)] main Process: [object Promise]
[INFO:CONSOLE(0)] getTitle: Google
[INFO:CONSOLE(0)] prototype.getTitle: Google
你不能,除非 API 以某种方式使之成为可能(见下文)。如果您使用的 Selenium API 被设计为异步工作,您不能强制它同步。我找不到您正在使用的 getTitle
调用的文档,但因为它是 returns 一个承诺,并且只能通过 then
回调(以及当你收到它时,promise 可能尚未解决),并且由于这些回调总是被异步调用(如果它们是 Promises/A+-compliant),你将不得不编写期望异步的代码。
如果这是你的目标,你可以使用 ES6 的箭头函数使回调更简洁:
driver.getTitle().then((title) => {
// .....
});
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
我认为现在要在 Node 中使用箭头函数,你必须使用像 Babel 这样的转译器。
关于链接文档的更新:API 可能 提供一项功能让您可以这样做:您可以使用 wait
,但很难说,因为文档已损坏:示例显示 wait
返回正在等待的东西(按钮):
var button = driver.wait(until.elementLocated(By.id('foo'), 10000);
button.click();
...但是文档清楚地写着 wait
returns 一个承诺:
Returns
webdriver.promise.Promise<T>
A promise that will be fulfilled with the first truthy value returned by the condition function, or rejected if the condition times out.
如果是后者错误(看起来很有可能),那么
var title = driver.wait(driver.getTitle(), 10000);
...标题最多等待 10 秒。或者,如果您的目标不是真正获得标题,而是获得名称为 q
的元素,那么这几乎与上面 wait
的示例完全相同:
driver.wait(until.elementLocated(By.name('q'), 10000).sendKeys('webdriver');
如果您使用的是新版本的 NodeJS(如 io.js(节点 3.0)或更高版本),您可以将 yield
与来自 bluebird 的 Promise.coroutine
一起使用(这可以在旧版本中通过 运行 --harmony-generators
标志激活):
Promise.coroutine(function*(){
var title = yield driver.getTitle(); // yield makes it wait
yield driver.findElement(By.name("q")).sendKeys("webdriver");
})();
如果你像 T.J 建议的那样使用 babel,你也可以使用异步函数:
(async function(){
let title = await driver.getTitle();
// ...
})();
我使用 selenium-webdriver 来测试 NodeJS。 我想以同步方式制作 selenium-webdriver API ,让我的测试非常简洁。
getTitle() 安排一个命令来检索当前页面的标题。这个APIreturn一个webdriver.promise.Promise
例如 selenium-webdriver 我做
driver.getTitle().then(function(title) {
.....
});
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
如何做到完全同步API(使API Promise 同步?),像这样
var titleElement = driver.getTitle();
var qElement= driver.findElement(webdriver.By.name('q'));
qElement.sendKeys('webdriver');
更新(Benjamin Gruenbaum 回复):
使用 yield with Promise.coroutine from bluebird API
function myBrowser() {
}
myBrowser.prototype.getTitle = Promise.coroutine(function* (driver) {
var title = yield driver.getTitle(); // yield makes it wait
console.log('prototype.getTitle: ' + title)
return title;
});
var driver = createDriver();
driver.get('https://www.google.fr/')
driver.getTitle().then(function(title) {
console.log('getTitle: ' + title)
});
// Use bluebird API
var mb = new myBrowser();
var title = mb.getTitle(driver)
// KO, It' an object Promise, not string title
console.log('main Process: ' + title)
输出
[INFO:CONSOLE(0)] main Process: [object Promise]
[INFO:CONSOLE(0)] getTitle: Google
[INFO:CONSOLE(0)] prototype.getTitle: Google
你不能,除非 API 以某种方式使之成为可能(见下文)。如果您使用的 Selenium API 被设计为异步工作,您不能强制它同步。我找不到您正在使用的 getTitle
调用的文档,但因为它是 returns 一个承诺,并且只能通过 then
回调(以及当你收到它时,promise 可能尚未解决),并且由于这些回调总是被异步调用(如果它们是 Promises/A+-compliant),你将不得不编写期望异步的代码。
如果这是你的目标,你可以使用 ES6 的箭头函数使回调更简洁:
driver.getTitle().then((title) => {
// .....
});
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
我认为现在要在 Node 中使用箭头函数,你必须使用像 Babel 这样的转译器。
关于链接文档的更新:API 可能 提供一项功能让您可以这样做:您可以使用 wait
,但很难说,因为文档已损坏:示例显示 wait
返回正在等待的东西(按钮):
var button = driver.wait(until.elementLocated(By.id('foo'), 10000);
button.click();
...但是文档清楚地写着 wait
returns 一个承诺:
Returns
webdriver.promise.Promise<T>
A promise that will be fulfilled with the first truthy value returned by the condition function, or rejected if the condition times out.
如果是后者错误(看起来很有可能),那么
var title = driver.wait(driver.getTitle(), 10000);
...标题最多等待 10 秒。或者,如果您的目标不是真正获得标题,而是获得名称为 q
的元素,那么这几乎与上面 wait
的示例完全相同:
driver.wait(until.elementLocated(By.name('q'), 10000).sendKeys('webdriver');
如果您使用的是新版本的 NodeJS(如 io.js(节点 3.0)或更高版本),您可以将 yield
与来自 bluebird 的 Promise.coroutine
一起使用(这可以在旧版本中通过 运行 --harmony-generators
标志激活):
Promise.coroutine(function*(){
var title = yield driver.getTitle(); // yield makes it wait
yield driver.findElement(By.name("q")).sendKeys("webdriver");
})();
如果你像 T.J 建议的那样使用 babel,你也可以使用异步函数:
(async function(){
let title = await driver.getTitle();
// ...
})();