承诺Angularjs 1.6如何强制函数等待api响应

时间:2017-02-21 14:01:31

标签: javascript angularjs angularjs-scope angular-promise

我正在使用这个插件:http://www.codingdrama.com/bootstrap-markdown/

我想挂钩onPreview

所以onPreview我试着打电话给我:

   app.directive("markdowntextarea",function ($http, $q) { // inject $q
    return {
        link: function (el_scope, element, attr) {
            element.markdown(
                {
                    autofocus: false,
                    savable: false,
                    onPreview: function (e) {
                        var deferred = $q.defer();
                        if (e.isDirty()) {
                            var originalContent = e.getContent();
                            $http({
                                url: '/api/markdown/',
                                data: {"body": originalContent, "actual_format": "md"},
                                method: 'POST'
                            }).then(function successCallback(response) {
                                console.log("successCallback", response.data.content);
                                deferred.resolve(response.data.content);
                            }, function errorCallback(response) {
                                console.log("errorCallback");
                                deferred.reject("error");
                            });
                        } else {
                            deferred.resolve("");
                        }
                        return deferred.promise;
                    }
                }
            );
        }
    }
});

控制台:

successCallback from api!!!

我从api获得了成功响应,response.data.content就是我想要使用的。这里的问题是return deferred.promise;总是返回原始值。我能在这做什么?我是angularjs的新手

3 个答案:

答案 0 :(得分:1)

使用promises,您无法立即返回值,通常您会返回名为promise handle的promise对象并使用'然后'你等待承诺解决(成功)或拒绝(失败)的条款。

在你的情况下,如果你想等待响应,然后做一些我建议你调用onPreview并使用它的then子句,如:

onPreview(e).then(function(response){}, function(error){});

onPreview已经回复了应该是可以接受的承诺。

编辑后:

所以onPreview是API方法,并期望文本不承诺,现在你可以做的是定义像makePreview之类的函数:

function makePreview(e) {
    var deferred = $q.defer();
    if (e.isDirty()) {
        var originalContent = e.getContent();
        $http({
            url: '/api/markdown/',
            data: {"body": originalContent, "actual_format": "md"},
            method: 'POST'
        }).then(function successCallback(response) {
            console.log("successCallback", response.data.content);
            deferred.resolve(response.config.data.body);
        }, function errorCallback(response) {
            console.log("errorCallback");
            deferred.reject("error");
        });
    } else {
        deferred.resolve("");
    }
    return deferred.promise;
}

然后你的onPreview应该是这样的:

autofocus: false,
savable: false,
onPreview: function (e) {
    makePreview(e).then(function(response){
        e.setContent(response);
        return response;
    }, function(error){
        return error;
    });
}

我希望这会有所帮助:)

答案 1 :(得分:0)

您无法以绝对同步方式写入角度。在回调中使用响应。 如果您需要控制api请求的订单,或等待多个请求,请参阅$q

的文档

答案 2 :(得分:-1)

然后您必须从 successCallback 函数中返回 response.data.content

这样的事情:



onPreview: function (e) {
                if (e.isDirty()) {
                    var originalContent = e.getContent();
                    return $http({
                        url: '/api/markdown/',
                        data: {"body": originalContent, "first": "1", "second": "2"},
                        method: 'POST'
                    }).then(function successCallback(response) {
                        console.log("successCallback", response.data.content);
                        return response.data.content;
                    }).catch(function errorCallback(response) {
                        console.log("errorCallback");
                        return response;
                    });
                }
            }