承诺语法/替代

时间:2016-06-06 06:55:55

标签: javascript asynchronous promise

我希望返回一个稍后会自行解决的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);
}

有没有更好的方法来实现此功能?

2 个答案:

答案 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),该函数将被调用以提供resolvereject函数:

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请求)。

相关问题