我希望返回一个稍后会自行解决的Promise,但似乎我的语法无效,我很好奇什么是更好的实现。为什么Promise构造函数需要执行程序?
promise = new Promise()
无效,因为我需要提供一个功能
function getDetails (someHash) {
var url = "http://somewebsite.com/" + someHash,
promise = new Promise();
makeAjaxRequest(url, function (response) {
promise.resolve(response.data);
});
setTimeout(function () {
promise.reject("timeout");
}, 500);
return promise;
}
function makeAjaxRequest (url, callback) {
var someResponse = {data: "some data"};
setTimeout(function () {
callback(someResponse);
}, 200);
}
有没有更好的方法来实现此功能?
答案 0 :(得分:4)
注意:如果您想将回调API转换为承诺,请参阅this question。
让我们从一开始就应该说些什么。为了设计承诺,执行者不是必需的。 完全可以设计一个类似于:
的promises实现let {promise, resolve, reject} = Promise.get();
如果你保证不告诉任何人,我甚至会告诉你一个小秘密 - 这个API甚至存在于规范的前一次迭代中,事实上甚至还可以在Chrome中使用:
let {promise, resolve, reject} = Promise.defer();
然而,它正被删除。
我just answered your other question关于为什么执行者是一个有趣的设计。这是安全的,它可以让你处理有趣的事情。
根据我的经验,我需要的大部分时间解决/拒绝我实际上需要它们。这就是说 - 事实上我确实需要他们几次。
说明符识别出这一点,因此执行函数始终是同步运行的。您可以获得.defer
接口,它不是默认接口:
function defer() {
let resolve, reject, promise = new Promise((res, rej) => {
[resolve, reject] = [res, rej];
});
return {resolve, reject, promise};
}
同样,这通常不是你想做的事情,但完全可能你有一个合理的用例,这就是为什么它不是默认但完全可能的
我首先将实现诸如超时和请求之类的东西作为原语,然后编写函数和链承诺:
function delay(ms) {
return new Promise(r => setTimeout(r, ms));
}
function timeout(promise, ms) {
return Promise.race([
promise,
delay(ms).then(x => { throw new Error("timeout"); })
]);
}
function ajax(url) { // note browsers do this natively with `fetch` today
return new Promise((resolve, reject) => { // handle errors!
makeAjaxRequest(url, (result) => {
// if(result.isFailure) reject(...);
if(result.status >= 400) reject(new Error(result.status));
else resolve(result.data);
});
});
}
现在,当我们宣传最低级API表面时,我们可以完全以声明方式编写上述代码:
function getDetails (someHash) {
var ajax = makeAjaxRequest("http://somewebsite.com/" + someHash);
return timeout(ajax, 500);
}
答案 1 :(得分:3)
您需要将函数传递给Promise
构造函数(more info),该函数将被调用以提供resolve
和reject
函数:
function getDetails (someHash) {
var url = "http://somewebsite.com/" + someHash;
return new Promise(function(resolve, reject) {
makeAjaxRequest(url, function(err, response) {
if (err)
reject(err);
else
resolve(response.data);
});
setTimeout(function () {
reject("timeout");
}, 500);
});
}
function makeAjaxRequest (url, callback) {
var someResponse = {data: "some data"};
setTimeout(function () {
callback(null, someResponse);
}, 200);
}
我还冒昧地让makeAjaxRequest
使用传递错误的标准惯例作为第一个参数(因为我假设在某些时候你想用实际的setTimeout()
替换import apollocaffe
from apollocaffe.layers import NumpyData, Convolution, EuclideanLoss
import numpy as np
def save():
net = apollocaffe.ApolloNet()
for i in range(1000):
example = np.array(np.random.random()).reshape((1, 1, 1, 1))
net.clear_forward()
net.f(NumpyData('data', example))
net.f(NumpyData('label', example*3))
net.f(Convolution('conv', (1,1), 1, bottoms=['data']))
net.f(EuclideanLoss('loss', bottoms=['conv', 'label']))
net.backward()
net.update(lr=0.1)
if i % 100 == 0:
print net.loss
net.save("model.h5")
def load():
print "LOAD"
net = apollocaffe.ApolloNet()
net.load("model.h5")
#example = np.array(np.random.random()).reshape((1, 1, 1, 1))
example = np.asarray([[[[ 0.92890837]]]])
net.clear_forward()
net.f(NumpyData('data', example))
net.f(NumpyData('label', example*3))
net.f(Convolution('conv', (1,1), 1, bottoms=['data']))
net.f(EuclideanLoss('loss', bottoms=['conv', 'label']))
net.backward()
net.update(lr=0.1)
print net.loss
save()
load()
AJAX请求)。